using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Lamb.UI; using MMBiomeGeneration; using Rewired; using TMPro; using Unify.Input; using UnityEngine; using UnityEngine.UI; using src.UINavigator; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ClassLibrary2")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ClassLibrary2")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("528f5a23-6efd-4f6b-85e8-1d3d74dfddd6")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace COTLMultiplayerTarotAddon; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.cotlmp.tarotaddon", "COTL Multiplayer Tarot Addon 8P", "0.3.0")] public sealed class TarotAddonPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("com.cotlmp.tarotaddon"); TarotPatches.EnsureClauneckTarotRoomsOnly(null, "Awake"); PatchIfFound(AccessTools.Method(typeof(Interaction_Tarot), "OnInteract", new Type[1] { typeof(StateMachine) }, (Type[])null), "InteractionTarot_OnInteract_Prefix", null, "Interaction_Tarot.OnInteract(StateMachine)"); PatchIfFound(AccessTools.Method(typeof(Interaction_Tarot), "DelayEffectsRoutine", new Type[3] { typeof(TarotCard), typeof(float), typeof(PlayerFarming) }, (Type[])null), "InteractionTarot_DelayEffectsRoutine_Prefix", "InteractionTarot_DelayEffectsRoutine_Postfix", "Interaction_Tarot.DelayEffectsRoutine"); PatchIfFound(AccessTools.Method(typeof(Interaction_Tarot), "OnDisable", (Type[])null, (Type[])null), null, "InteractionTarot_OnDisable_Postfix", "Interaction_Tarot.OnDisable"); PatchIfFound(AccessTools.Method(typeof(Interaction_Tarot), "DoRoutine", (Type[])null, (Type[])null), "InteractionTarot_DoRoutine_Prefix", null, "Interaction_Tarot.DoRoutine()"); PatchIfFound(AccessTools.Method(typeof(Interaction_TarotCard), "OnInteract", new Type[1] { typeof(StateMachine) }, (Type[])null), "InteractionTarotCard_OnInteract_Prefix", null, "Interaction_TarotCard.OnInteract(StateMachine)"); PatchIfFound(AccessTools.Method(typeof(Interaction_TarotCard), "DoRoutine", (Type[])null, (Type[])null), "InteractionTarotCard_DoRoutine_Prefix", null, "Interaction_TarotCard.DoRoutine()"); PatchIfFound(AccessTools.Method(typeof(Interaction_TarotCard), "DelayEffectsRoutine", new Type[1] { typeof(PlayerFarming) }, (Type[])null), "InteractionTarotCard_DelayEffectsRoutine_Prefix", null, "Interaction_TarotCard.DelayEffectsRoutine(PlayerFarming)"); PatchIfFound(AccessTools.Method(typeof(Interaction_TarotCard), "OnDisable", (Type[])null, (Type[])null), null, "InteractionTarotCard_OnDisable_Postfix", "Interaction_TarotCard.OnDisable"); PatchIfFound(AccessTools.Method(typeof(Interaction_Chest), "SelectReward", (Type[])null, (Type[])null), null, "InteractionChest_SelectReward_Postfix", "Interaction_Chest.SelectReward()"); PatchIfFound(AccessTools.Method(typeof(Interaction_Chest), "OnDisableInteraction", Type.EmptyTypes, (Type[])null), null, "InteractionChest_OnDisableInteraction_Postfix", "Interaction_Chest.OnDisableInteraction()"); PatchIfFound(AccessTools.Method(typeof(InventoryItem), "Spawn", new Type[5] { typeof(ITEM_TYPE), typeof(int), typeof(Vector3), typeof(float), typeof(Action) }, (Type[])null), "InventoryItem_Spawn_Prefix", null, "InventoryItem.Spawn(ITEM_TYPE,int,Vector3,float,Action)"); PatchIfFound(AccessTools.Method(typeof(BiomeGenerator), "Generate", Type.EmptyTypes, (Type[])null), "BiomeGenerator_Generate_Prefix", null, "BiomeGenerator.Generate()"); PatchIfFound(AccessTools.Method(typeof(Shrines), "OnInteract", new Type[1] { typeof(StateMachine) }, (Type[])null), "Shrines_OnInteract_Prefix", null, "Shrines.OnInteract(StateMachine)"); PatchIfFound(AccessTools.Method(typeof(Shrines), "DrawCardRoutine", new Type[1] { typeof(PlayerFarming) }, (Type[])null), "Shrines_DrawCardRoutine_Prefix", null, "Shrines.DrawCardRoutine(PlayerFarming)"); PatchIfFound(AccessTools.Method(typeof(Shrines), "DelayEffectsRoutine", new Type[3] { typeof(TarotCard), typeof(float), typeof(PlayerFarming) }, (Type[])null), "Shrines_DelayEffectsRoutine_Prefix", "Shrines_DelayEffectsRoutine_Postfix", "Shrines.DelayEffectsRoutine(TarotCard,float,PlayerFarming)"); PatchIfFound(AccessTools.Method(typeof(UITarotChoiceOverlayController), "Show", new Type[3] { typeof(TarotCard), typeof(TarotCard), typeof(bool) }, (Type[])null), null, "TarotChoiceOverlay_Show_Postfix", "UITarotChoiceOverlayController.Show"); PatchIfFound(AccessTools.Method(typeof(Shrines), "OnDisable", Type.EmptyTypes, (Type[])null), null, "Shrines_OnDisable_Postfix", "Shrines.OnDisable()"); Log.LogInfo((object)"Tarot addon 8P loaded."); } private void PatchIfFound(MethodInfo original, string prefix = null, string postfix = null, string originalLabel = null) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if (original == null) { Log.LogWarning((object)("[Tarot] Skipped patch (method missing): " + (originalLabel ?? "unknown"))); return; } HarmonyMethod val = null; HarmonyMethod val2 = null; if (!string.IsNullOrEmpty(prefix)) { val = new HarmonyMethod(typeof(TarotPatches), prefix, (Type[])null); } if (!string.IsNullOrEmpty(postfix)) { val2 = new HarmonyMethod(typeof(TarotPatches), postfix, (Type[])null); } _harmony.Patch((MethodBase)original, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } internal sealed class TarotChoiceOwnerBanner : MonoBehaviour { private static readonly FieldInfo Indicator1Field = AccessTools.Field(typeof(UITarotChoiceOverlayController), "coopIndicator_card1"); private static readonly FieldInfo Indicator2Field = AccessTools.Field(typeof(UITarotChoiceOverlayController), "coopIndicator_card2"); private UITarotChoiceOverlayController _overlay; private CoopIndicatorIcon _indicator1; private CoopIndicatorIcon _indicator2; private TextMeshProUGUI _label; public static void Attach(UITarotChoiceOverlayController overlay, PlayerFarming owner) { if (!((Object)(object)overlay == (Object)null)) { TarotChoiceOwnerBanner tarotChoiceOwnerBanner = ((Component)overlay).GetComponent(); if ((Object)(object)tarotChoiceOwnerBanner == (Object)null) { tarotChoiceOwnerBanner = ((Component)overlay).gameObject.AddComponent(); } tarotChoiceOwnerBanner._overlay = overlay; tarotChoiceOwnerBanner._indicator1 = (CoopIndicatorIcon)((Indicator1Field != null) ? /*isinst with value type is only supported in some contexts*/: null); tarotChoiceOwnerBanner._indicator2 = (CoopIndicatorIcon)((Indicator2Field != null) ? /*isinst with value type is only supported in some contexts*/: null); tarotChoiceOwnerBanner.CreateOrRefreshLabel(owner); tarotChoiceOwnerBanner.HideVanillaOwnerIcons(); } } private void LateUpdate() { HideVanillaOwnerIcons(); if ((Object)(object)_label != (Object)null) { ((TMP_Text)_label).transform.SetAsLastSibling(); } } private void HideVanillaOwnerIcons() { if ((Object)(object)_indicator1 != (Object)null && ((Component)_indicator1).gameObject.activeSelf) { ((Component)_indicator1).gameObject.SetActive(false); } if ((Object)(object)_indicator2 != (Object)null && ((Component)_indicator2).gameObject.activeSelf) { ((Component)_indicator2).gameObject.SetActive(false); } } private void CreateOrRefreshLabel(PlayerFarming owner) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_overlay == (Object)null) { return; } if ((Object)(object)_label == (Object)null) { GameObject val = new GameObject("COTLMP Tarot Owner Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(((Component)_overlay).transform, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, -38f); component.sizeDelta = new Vector2(900f, 72f); _label = val.GetComponent(); TextMeshProUGUI componentInChildren = ((Component)_overlay).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)_label).font = ((TMP_Text)componentInChildren).font; ((TMP_Text)_label).fontSharedMaterial = ((TMP_Text)componentInChildren).fontSharedMaterial; } ((TMP_Text)_label).fontSize = 38f; ((TMP_Text)_label).fontStyle = (FontStyles)1; ((TMP_Text)_label).alignment = (TextAlignmentOptions)514; ((Graphic)_label).color = Color.white; ((TMP_Text)_label).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)_label).outlineWidth = 0.2f; ((Graphic)_label).raycastTarget = false; } int num = ((!((Object)(object)owner != (Object)null)) ? 1 : (owner.playerID + 1)); ((TMP_Text)_label).text = "PLAYER " + num + " - CHOOSE YOUR TAROT CARD"; Color playerColor = GetPlayerColor(num - 1); ((Graphic)_label).color = playerColor; } private static Color GetPlayerColor(int playerID) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_005c: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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) Color[] array = (Color[])(object)new Color[8] { new Color(1f, 0.3f, 0.3f, 1f), new Color(0.7f, 0.45f, 1f, 1f), new Color(1f, 0.65f, 0.15f, 1f), new Color(0.45f, 0.75f, 1f, 1f), new Color(0.3f, 1f, 0.4f, 1f), new Color(1f, 0.9f, 0.2f, 1f), new Color(0.2f, 1f, 1f, 1f), new Color(1f, 0.4f, 0.8f, 1f) }; return array[Mathf.Clamp(playerID, 0, array.Length - 1)]; } } internal static class TarotPatches { private const int MaxPlayers = 8; private static bool VERBOSE_LOGS = false; private const string ClauneckTarotRoomPath = "Assets/_Rooms/Reward Room Tarot.prefab"; private const string CardsOnlyTarotRoomPath = "Assets/_Rooms/Special Free Tarot Cards.prefab"; private static bool _loggedTarotRoomPolicy = false; private static readonly Dictionary TarotOwnerByInstance = new Dictionary(); private static readonly Dictionary> PendingTarotQueueByInstance = new Dictionary>(); private static readonly HashSet WarnedSuppressedDiscardByInstance = new HashSet(); private static readonly Dictionary TarotCardOwnerByInstance = new Dictionary(); private static readonly Dictionary ShrineTarotOwnerByInstance = new Dictionary(); private static readonly Dictionary> PendingShrineTarotQueueByInstance = new Dictionary>(); private static readonly HashSet WarnedSuppressedShrineDiscardByInstance = new HashSet(); private static readonly Dictionary PendingChestTarotExtraByChest = new Dictionary(); private static readonly Dictionary PendingChestTarotExpiryByChest = new Dictionary(); private static int PendingChestTarotExtraAny = 0; private static float PendingChestTarotAnyExpiry = -1f; private static int PendingChestTarotSourceChestId = 0; private static readonly Dictionary RecentChestRewardWindowByChest = new Dictionary(); private static readonly Dictionary RecentChestRewardPositionByChest = new Dictionary(); private static int RecentChestRewardSourceChestId = 0; private static float RecentChestRewardAnyExpiry = -1f; private const float RecentChestRewardWindowSeconds = 8f; private const float ChestTarotFallbackRadius = 6f; private static readonly FieldInfo InteractionChestRewardField = typeof(Interaction_Chest).GetField("Reward", BindingFlags.Instance | BindingFlags.NonPublic); private static bool IsSpawningExtraChestTarot = false; public static void BiomeGenerator_Generate_Prefix(BiomeGenerator __instance) { EnsureClauneckTarotRoomsOnly(__instance, "BiomeGenerator.Generate"); } internal static void EnsureClauneckTarotRoomsOnly(BiomeGenerator biomeGenerator, string reason) { try { if (!_loggedTarotRoomPolicy) { _loggedTarotRoomPolicy = true; TarotAddonPlugin.Log.LogInfo((object)"[TarotRoom] Vanilla tarot-room behavior preserved (no tarot room path filtering)."); } } catch (Exception ex) { TarotAddonPlugin.Log.LogWarning((object)("[TarotRoom] Failed to enforce tarot room policy during " + reason + ": " + ex.Message)); } } private static int RemoveDisallowedTarotRoomPaths(List roomPaths) { return 0; } private static bool IsDisallowedTarotRoomPath(string candidate) { if (string.IsNullOrEmpty(candidate)) { return false; } string text = NormalizeRoomPath(candidate); if (string.Equals(text, NormalizeRoomPath("Assets/_Rooms/Reward Room Tarot.prefab"), StringComparison.OrdinalIgnoreCase)) { return false; } return text.IndexOf("tarot", StringComparison.OrdinalIgnoreCase) >= 0; } private static string NormalizeRoomPath(string path) { if (string.IsNullOrEmpty(path)) { return string.Empty; } return path.Replace('\\', '/').Trim(); } public static void InteractionTarot_OnInteract_Prefix(Interaction_Tarot __instance, StateMachine state) { if ((Object)(object)__instance == (Object)null || (Object)(object)state == (Object)null) { return; } PlayerFarming val = ResolvePlayerFromState(state); if ((Object)(object)val == (Object)null) { return; } TrySetAllowedInputPlayer(val); SetInteractionContext(__instance, val, state); int instanceID = ((Object)__instance).GetInstanceID(); if (PendingTarotQueueByInstance.ContainsKey(instanceID) || __instance.Activated) { return; } Queue queue = BuildTarotQueue(val); if (queue.Count > 0) { PendingTarotQueueByInstance[instanceID] = queue; if (VERBOSE_LOGS) { TarotAddonPlugin.Log.LogInfo((object)("[Tarot] Queue created for instance " + instanceID + ".")); } } } public static bool InteractionTarot_DelayEffectsRoutine_Prefix(Interaction_Tarot __instance, TarotCard card, float delay, ref PlayerFarming playerFarming, ref IEnumerator __result) { if ((Object)(object)__instance == (Object)null) { return true; } PlayerFarming trackedTarotOwner = GetTrackedTarotOwner(__instance); if ((Object)(object)trackedTarotOwner == (Object)null) { return true; } if ((Object)(object)playerFarming != (Object)(object)trackedTarotOwner) { int instanceID = ((Object)__instance).GetInstanceID(); if (WarnedSuppressedDiscardByInstance.Add(instanceID)) { TarotAddonPlugin.Log.LogInfo((object)("[Tarot] Suppressed vanilla discard grant; P" + (trackedTarotOwner.playerID + 1) + " keeps only the card they chose.")); } __result = SuppressedDelayRoutine(delay); return false; } if ((Object)(object)playerFarming == (Object)null) { playerFarming = trackedTarotOwner; } return true; } public static void InteractionTarot_DelayEffectsRoutine_Postfix(Interaction_Tarot __instance, TarotCard card, float delay, PlayerFarming playerFarming, ref IEnumerator __result) { if (!((Object)(object)__instance == (Object)null) && __result != null) { PlayerFarming trackedTarotOwner = GetTrackedTarotOwner(__instance); if (!((Object)(object)trackedTarotOwner == (Object)null) && !((Object)(object)playerFarming != (Object)(object)trackedTarotOwner)) { __result = WrapAndAdvanceTarotQueue(__result, __instance, trackedTarotOwner); } } } public static void InteractionTarot_OnDisable_Postfix(Interaction_Tarot __instance) { if (!((Object)(object)__instance == (Object)null)) { int instanceID = ((Object)__instance).GetInstanceID(); TarotOwnerByInstance.Remove(instanceID); PendingTarotQueueByInstance.Remove(instanceID); WarnedSuppressedDiscardByInstance.Remove(instanceID); } } public static void InteractionTarot_DoRoutine_Prefix(Interaction_Tarot __instance) { if ((Object)(object)__instance == (Object)null) { return; } int instanceID = ((Object)__instance).GetInstanceID(); PlayerFarming trackedTarotOwner = GetTrackedTarotOwner(__instance); if ((Object)(object)trackedTarotOwner == (Object)null) { return; } StateMachine val = TryResolveInteractionState(__instance); if ((Object)(object)val == (Object)null && (Object)(object)trackedTarotOwner != (Object)null) { val = trackedTarotOwner.state; } TrySetAllowedInputPlayer(trackedTarotOwner); SetInteractionContext(__instance, trackedTarotOwner, val); if (!PendingTarotQueueByInstance.ContainsKey(instanceID)) { Queue queue = BuildTarotQueue(trackedTarotOwner); if (queue.Count > 0) { PendingTarotQueueByInstance[instanceID] = queue; TarotAddonPlugin.Log.LogInfo((object)("[Tarot] Bootstrapped chained queue for P" + (trackedTarotOwner.playerID + 1) + ".")); } } } public static void Shrines_OnInteract_Prefix(Shrines __instance, StateMachine state) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (Object)(object)state == (Object)null || (int)__instance.TypeOfShrine != 7) { return; } PlayerFarming val = ResolvePlayerFromState(state); if ((Object)(object)val == (Object)null) { return; } TrySetAllowedInputPlayer(val); SetInteractionContext(__instance, val, state); int instanceID = ((Object)__instance).GetInstanceID(); ShrineTarotOwnerByInstance[instanceID] = val; if (!PendingShrineTarotQueueByInstance.ContainsKey(instanceID)) { Queue queue = BuildTarotQueue(val); if (queue.Count > 0) { PendingShrineTarotQueueByInstance[instanceID] = queue; TarotAddonPlugin.Log.LogInfo((object)("[ShrineTarot] Queue created for instance " + instanceID + ".")); } } } public static void Shrines_DrawCardRoutine_Prefix(Shrines __instance, ref PlayerFarming playerFarming) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (int)__instance.TypeOfShrine != 7) { return; } PlayerFarming val = playerFarming; if ((Object)(object)val == (Object)null) { val = GetTrackedShrineTarotOwner(__instance); } if ((Object)(object)val == (Object)null) { val = TryResolveInteractionPlayer(__instance); } if ((Object)(object)val == (Object)null) { return; } playerFarming = val; TrySetAllowedInputPlayer(val); SetInteractionContext(__instance, val, val.state); int instanceID = ((Object)__instance).GetInstanceID(); ShrineTarotOwnerByInstance[instanceID] = val; if (!PendingShrineTarotQueueByInstance.ContainsKey(instanceID)) { Queue queue = BuildTarotQueue(val); if (queue.Count > 0) { PendingShrineTarotQueueByInstance[instanceID] = queue; TarotAddonPlugin.Log.LogInfo((object)("[ShrineTarot] Bootstrapped queue for P" + (val.playerID + 1) + ".")); } } } public static bool Shrines_DelayEffectsRoutine_Prefix(Shrines __instance, TarotCard card, float delay, ref PlayerFarming playerFarming, ref IEnumerator __result) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null) { return true; } if ((int)__instance.TypeOfShrine != 7) { return true; } PlayerFarming trackedShrineTarotOwner = GetTrackedShrineTarotOwner(__instance); if ((Object)(object)trackedShrineTarotOwner == (Object)null) { return true; } if ((Object)(object)playerFarming != (Object)(object)trackedShrineTarotOwner) { int instanceID = ((Object)__instance).GetInstanceID(); if (WarnedSuppressedShrineDiscardByInstance.Add(instanceID)) { TarotAddonPlugin.Log.LogInfo((object)("[ShrineTarot] Suppressed vanilla discard grant; P" + (trackedShrineTarotOwner.playerID + 1) + " keeps only the card they chose.")); } __result = SuppressedDelayRoutine(delay); return false; } if ((Object)(object)playerFarming == (Object)null) { playerFarming = trackedShrineTarotOwner; } return true; } public static void Shrines_DelayEffectsRoutine_Postfix(Shrines __instance, TarotCard card, float delay, PlayerFarming playerFarming, ref IEnumerator __result) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (!((Object)(object)__instance == (Object)null) && __result != null && (int)__instance.TypeOfShrine == 7) { PlayerFarming trackedShrineTarotOwner = GetTrackedShrineTarotOwner(__instance); if (!((Object)(object)trackedShrineTarotOwner == (Object)null) && !((Object)(object)playerFarming != (Object)(object)trackedShrineTarotOwner)) { __result = WrapAndAdvanceShrineTarotQueue(__result, __instance, trackedShrineTarotOwner); } } } public static void Shrines_OnDisable_Postfix(Shrines __instance) { if (!((Object)(object)__instance == (Object)null)) { CleanupShrineTarotState(((Object)__instance).GetInstanceID()); } } public static void InteractionTarotCard_OnInteract_Prefix(Interaction_TarotCard __instance, StateMachine state) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)state == (Object)null)) { PlayerFarming val = ResolvePlayerFromState(state); if (!((Object)(object)val == (Object)null)) { TrySetAllowedInputPlayer(val); SetInteractionContext(__instance, val, state); int instanceID = ((Object)__instance).GetInstanceID(); TarotCardOwnerByInstance[instanceID] = val; } } } public static void InteractionTarotCard_DoRoutine_Prefix(Interaction_TarotCard __instance) { if ((Object)(object)__instance == (Object)null) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (!TarotCardOwnerByInstance.TryGetValue(instanceID, out var value) || (Object)(object)value == (Object)null) { value = TryResolveInteractionPlayer(__instance); } if (!((Object)(object)value == (Object)null)) { StateMachine val = TryResolveInteractionState(__instance); if ((Object)(object)val == (Object)null && (Object)(object)value != (Object)null) { val = value.state; } TrySetAllowedInputPlayer(value); SetInteractionContext(__instance, value, val); TarotCardOwnerByInstance[instanceID] = value; } } public static bool InteractionTarotCard_DelayEffectsRoutine_Prefix(Interaction_TarotCard __instance, ref PlayerFarming playerFarming) { if ((Object)(object)__instance == (Object)null) { return true; } int instanceID = ((Object)__instance).GetInstanceID(); if (!TarotCardOwnerByInstance.TryGetValue(instanceID, out var value)) { value = TryResolveInteractionPlayer(__instance); } if ((Object)(object)value == (Object)null) { return true; } if ((Object)(object)playerFarming == (Object)null || (Object)(object)playerFarming != (Object)(object)value) { playerFarming = value; if (VERBOSE_LOGS) { TarotAddonPlugin.Log.LogInfo((object)("[TarotCard] Rebound reward ownership to P" + (value.playerID + 1) + ".")); } } return true; } public unsafe static void InteractionChest_SelectReward_Postfix(Interaction_Chest __instance) { //IL_0017: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null) { return; } int instanceID = ((Object)__instance).GetInstanceID(); ClearPendingChestTarot(instanceID); Vector3 value = Vector3.zero; bool flag = false; try { value = ((Component)__instance).transform.position; flag = true; } catch { } int effectivePlayerCountForChestTarot = GetEffectivePlayerCountForChestTarot(); int num = Mathf.Clamp(effectivePlayerCountForChestTarot - 2, 0, 2); if (num <= 0) { return; } RecentChestRewardWindowByChest[instanceID] = Time.unscaledTime + 8f; if (flag) { RecentChestRewardPositionByChest[instanceID] = value; } RecentChestRewardSourceChestId = instanceID; RecentChestRewardAnyExpiry = Time.unscaledTime + 6f; if (TryGetChestReward(__instance, out var reward)) { TarotAddonPlugin.Log.LogInfo((object)("[TarotCard] Chest reward rolled: " + ((object)(*(ITEM_TYPE*)(&reward))/*cast due to .constrained prefix*/).ToString())); if ((int)reward != 26) { TarotAddonPlugin.Log.LogInfo((object)"[TarotCard] Chest did not roll tarot card this time."); return; } PendingChestTarotExtraByChest[instanceID] = num; PendingChestTarotExpiryByChest[instanceID] = Time.unscaledTime + 10f; PendingChestTarotExtraAny = num; PendingChestTarotAnyExpiry = Time.unscaledTime + 6f; PendingChestTarotSourceChestId = instanceID; TarotAddonPlugin.Log.LogInfo((object)("[TarotCard] Chest tarot bonus prepared: +" + num + " card(s) for effectivePlayers=" + effectivePlayerCountForChestTarot + " (playersCount=" + PlayerFarming.playersCount + ").")); } } public static void InteractionChest_OnDisableInteraction_Postfix(Interaction_Chest __instance) { _ = (Object)(object)__instance == (Object)null; } public static void InventoryItem_Spawn_Prefix(ITEM_TYPE type, int quantity, Vector3 position, float StartSpeed, Action result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) if (IsSpawningExtraChestTarot || (int)type != 26 || quantity <= 0) { return; } int value = 0; int num = 0; Interaction_Chest instance = Interaction_Chest.Instance; if ((Object)(object)instance != (Object)null) { int instanceID = ((Object)instance).GetInstanceID(); num = instanceID; if (PendingChestTarotExpiryByChest.TryGetValue(instanceID, out var value2) && Time.unscaledTime > value2) { ClearPendingChestTarot(instanceID); } else if (!PendingChestTarotExtraByChest.TryGetValue(instanceID, out value)) { value = 0; } } if (value <= 0 && PendingChestTarotExtraAny > 0) { if (PendingChestTarotAnyExpiry > 0f && Time.unscaledTime > PendingChestTarotAnyExpiry) { ClearPendingChestTarotAny(); } else { value = PendingChestTarotExtraAny; if (num == 0) { num = PendingChestTarotSourceChestId; } } } if (value <= 0) { Interaction_Chest instance2 = Interaction_Chest.Instance; if ((Object)(object)instance2 != (Object)null) { int instanceID2 = ((Object)instance2).GetInstanceID(); if (RecentChestRewardWindowByChest.TryGetValue(instanceID2, out var value3)) { if (Time.unscaledTime > value3) { ClearRecentChestRewardState(instanceID2); } else { bool flag = true; try { flag = Vector3.Distance(((Component)instance2).transform.position, position) <= 6f; } catch { flag = true; } if (flag) { int effectivePlayerCountForChestTarot = GetEffectivePlayerCountForChestTarot(); value = Mathf.Clamp(effectivePlayerCountForChestTarot - 2, 0, 2); if (value > 0) { num = instanceID2; TarotAddonPlugin.Log.LogInfo((object)("[TarotCard] Chest tarot fallback engaged: +" + value + " card(s) for effectivePlayers=" + effectivePlayerCountForChestTarot + ".")); } } } } } else if (RecentChestRewardAnyExpiry > 0f) { if (Time.unscaledTime > RecentChestRewardAnyExpiry) { if (RecentChestRewardSourceChestId != 0) { RecentChestRewardPositionByChest.Remove(RecentChestRewardSourceChestId); } RecentChestRewardAnyExpiry = -1f; RecentChestRewardSourceChestId = 0; } else { int recentChestRewardSourceChestId = RecentChestRewardSourceChestId; bool flag2 = true; if (recentChestRewardSourceChestId != 0 && RecentChestRewardPositionByChest.TryGetValue(recentChestRewardSourceChestId, out var value4)) { flag2 = Vector3.Distance(value4, position) <= 6f; } if (flag2) { int effectivePlayerCountForChestTarot2 = GetEffectivePlayerCountForChestTarot(); value = Mathf.Clamp(effectivePlayerCountForChestTarot2 - 2, 0, 2); if (value > 0) { num = recentChestRewardSourceChestId; TarotAddonPlugin.Log.LogInfo((object)("[TarotCard] Chest tarot fallback(any) engaged: +" + value + " card(s) for effectivePlayers=" + effectivePlayerCountForChestTarot2 + ".")); } } } } } if (value <= 0) { return; } try { IsSpawningExtraChestTarot = true; Vector3 val = default(Vector3); for (int i = 0; i < value; i++) { ((Vector3)(ref val))..ctor(Random.Range(-0.35f, 0.35f), Random.Range(-0.2f, 0.2f), 0f); InventoryItem.Spawn(type, 1, position + val, StartSpeed, result); } TarotAddonPlugin.Log.LogInfo((object)("[TarotCard] Chest tarot multiplied: base drop + " + value + " extra.")); } catch (Exception ex) { TarotAddonPlugin.Log.LogWarning((object)("[TarotCard] Failed chest tarot multiply: " + ex.Message)); } finally { IsSpawningExtraChestTarot = false; if (num != 0) { if (PendingChestTarotExpiryByChest.TryGetValue(num, out var value5) && Time.unscaledTime > value5) { ClearPendingChestTarot(num); } if (RecentChestRewardWindowByChest.TryGetValue(num, out var value6) && Time.unscaledTime > value6) { ClearRecentChestRewardState(num); } } if (PendingChestTarotAnyExpiry > 0f && Time.unscaledTime > PendingChestTarotAnyExpiry) { ClearPendingChestTarotAny(); } if (RecentChestRewardAnyExpiry > 0f && Time.unscaledTime > RecentChestRewardAnyExpiry) { if (RecentChestRewardSourceChestId != 0) { RecentChestRewardPositionByChest.Remove(RecentChestRewardSourceChestId); } RecentChestRewardAnyExpiry = -1f; RecentChestRewardSourceChestId = 0; } } } public static void InteractionTarotCard_OnDisable_Postfix(Interaction_TarotCard __instance) { if (!((Object)(object)__instance == (Object)null)) { CleanupTarotCardState(((Object)__instance).GetInstanceID()); } } private static void CleanupTarotCardState(int interactionId) { TarotCardOwnerByInstance.Remove(interactionId); } private static bool TryGetChestReward(Interaction_Chest chest, out ITEM_TYPE reward) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected I4, but got Unknown reward = (ITEM_TYPE)0; if ((Object)(object)chest == (Object)null || InteractionChestRewardField == null) { return false; } try { object value = InteractionChestRewardField.GetValue(chest); if (value is ITEM_TYPE) { reward = (ITEM_TYPE)(int)(ITEM_TYPE)value; return true; } } catch { } return false; } private static int GetEffectivePlayerCountForChestTarot() { int num = Mathf.Clamp(PlayerFarming.playersCount, 0, 8); HashSet hashSet = new HashSet(); int num2 = CountRelaxedActivePlayerSlots(); if (CoopManager.AllPlayerGameObjects != null) { int num3 = Mathf.Min(CoopManager.AllPlayerGameObjects.Length, 8); for (int i = 0; i < num3; i++) { GameObject val = CoopManager.AllPlayerGameObjects[i]; if ((Object)(object)val != (Object)null && val.activeInHierarchy) { hashSet.Add(i); } } } int num4 = Mathf.Max(hashSet.Count, num2); int num5 = 0; for (int j = 0; j < 8; j++) { if (HasInputAssignedToSlot(j)) { num5++; } } int num6 = Mathf.Max(new int[3] { num, num4, num5 }); if (num6 <= 0) { num6 = 1; } return Mathf.Clamp(num6, 1, 8); } private static int CountRelaxedActivePlayerSlots() { if (PlayerFarming.players == null) { return 0; } HashSet hashSet = new HashSet(); for (int i = 0; i < PlayerFarming.players.Count; i++) { PlayerFarming val = PlayerFarming.players[i]; if (!((Object)(object)val == (Object)null) && val.playerID >= 0 && val.playerID < 8 && !((Object)(object)val.state == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy && HasUsableInput(val)) { hashSet.Add(val.playerID); } } return hashSet.Count; } private static bool HasInputAssignedToSlot(int slot) { try { Player player = RewiredInputManager.GetPlayer(slot); if (player == null || player.controllers == null) { return false; } if (player.controllers.hasKeyboard) { return true; } return player.controllers.Joysticks != null && player.controllers.Joysticks.Count > 0; } catch { return false; } } private static void ClearPendingChestTarot(int chestId) { PendingChestTarotExtraByChest.Remove(chestId); PendingChestTarotExpiryByChest.Remove(chestId); } private static void ClearPendingChestTarotAny() { PendingChestTarotExtraAny = 0; PendingChestTarotAnyExpiry = -1f; PendingChestTarotSourceChestId = 0; } private static void ClearRecentChestRewardState(int chestId) { if (chestId != 0) { RecentChestRewardWindowByChest.Remove(chestId); RecentChestRewardPositionByChest.Remove(chestId); if (RecentChestRewardSourceChestId == chestId) { RecentChestRewardSourceChestId = 0; RecentChestRewardAnyExpiry = -1f; } } } private static IEnumerator WrapAndAdvanceTarotQueue(IEnumerator original, Interaction_Tarot interaction, PlayerFarming owner) { while (SafeMoveNext(original)) { yield return original.Current; } if ((Object)(object)interaction == (Object)null) { yield break; } int id = ((Object)interaction).GetInstanceID(); if (!PendingTarotQueueByInstance.TryGetValue(id, out var queue) || queue == null || queue.Count == 0) { CleanupInteractionState(id); yield break; } yield return (object)new WaitForSeconds(0.05f); while (queue.Count > 0) { PlayerFarming activePlayerBySlot = GetActivePlayerBySlot(queue.Dequeue()); if (!((Object)(object)activePlayerBySlot == (Object)null) && (!((Object)(object)owner != (Object)null) || !((Object)(object)activePlayerBySlot == (Object)(object)owner))) { if (!((Behaviour)interaction).isActiveAndEnabled) { CleanupInteractionState(id); } else { TriggerNextTarotInteraction(interaction, activePlayerBySlot); } yield break; } } CleanupInteractionState(id); } private static void TriggerNextTarotInteraction(Interaction_Tarot interaction, PlayerFarming player) { if ((Object)(object)interaction == (Object)null || (Object)(object)player == (Object)null || (Object)(object)player.state == (Object)null) { return; } try { TrySetAllowedInputPlayer(player); SetInteractionContext(interaction, player, player.state); interaction.Activated = false; TarotAddonPlugin.Log.LogInfo((object)("[Tarot] Chained selection owner -> P" + (player.playerID + 1) + ".")); ((Interaction)interaction).OnInteract(player.state); if (VERBOSE_LOGS) { TarotAddonPlugin.Log.LogInfo((object)("[Tarot] Triggered chained interaction for P" + (player.playerID + 1) + ".")); } } catch (Exception ex) { TarotAddonPlugin.Log.LogWarning((object)("[Tarot] Failed to trigger chained interaction: " + ex.Message)); CleanupInteractionState(((Object)interaction).GetInstanceID()); } } private static IEnumerator WrapAndAdvanceShrineTarotQueue(IEnumerator original, Shrines shrine, PlayerFarming owner) { while (SafeMoveNext(original)) { yield return original.Current; } if ((Object)(object)shrine == (Object)null) { yield break; } int id = ((Object)shrine).GetInstanceID(); if (!PendingShrineTarotQueueByInstance.TryGetValue(id, out var queue) || queue == null || queue.Count == 0) { CleanupShrineTarotState(id); yield break; } yield return (object)new WaitForSeconds(0.05f); while (queue.Count > 0) { PlayerFarming activePlayerBySlot = GetActivePlayerBySlot(queue.Dequeue()); if (!((Object)(object)activePlayerBySlot == (Object)null) && (!((Object)(object)owner != (Object)null) || !((Object)(object)activePlayerBySlot == (Object)(object)owner))) { if (!((Behaviour)shrine).isActiveAndEnabled) { CleanupShrineTarotState(id); } else { TriggerNextShrineTarotInteraction(shrine, activePlayerBySlot); } yield break; } } CleanupShrineTarotState(id); } private static void TriggerNextShrineTarotInteraction(Shrines shrine, PlayerFarming player) { if ((Object)(object)shrine == (Object)null || (Object)(object)player == (Object)null || (Object)(object)player.state == (Object)null) { return; } int instanceID = ((Object)shrine).GetInstanceID(); try { TrySetAllowedInputPlayer(player); SetInteractionContext(shrine, player, player.state); ShrineTarotOwnerByInstance[instanceID] = player; if (!(Traverse.Create((object)shrine).Method("DrawCardRoutine", new object[1] { player }).GetValue() is IEnumerator enumerator)) { TarotAddonPlugin.Log.LogWarning((object)("[ShrineTarot] Failed to resolve DrawCardRoutine for P" + (player.playerID + 1) + ".")); CleanupShrineTarotState(instanceID); } else { TarotAddonPlugin.Log.LogInfo((object)("[ShrineTarot] Chained purchase owner -> P" + (player.playerID + 1) + ".")); ((MonoBehaviour)shrine).StartCoroutine(enumerator); } } catch (Exception ex) { TarotAddonPlugin.Log.LogWarning((object)("[ShrineTarot] Failed to trigger chained purchase: " + ex.Message)); CleanupShrineTarotState(instanceID); } } private static Queue BuildTarotQueue(PlayerFarming starter) { Queue queue = new Queue(); if ((Object)(object)starter == (Object)null) { return queue; } int num = Mathf.Clamp(starter.playerID, 0, 7); for (int i = 1; i < 8; i++) { int slot = (num + i) % 8; EnqueueSlotIfActive(queue, slot); } return queue; } public static void TarotChoiceOverlay_Show_Postfix(UITarotChoiceOverlayController __instance) { if (!((Object)(object)__instance == (Object)null)) { PlayerFarming owner = null; try { owner = (((Object)(object)MonoSingleton.Instance != (Object)null) ? MonoSingleton.Instance.AllowInputOnlyFromPlayer : null); } catch { } TarotChoiceOwnerBanner.Attach(__instance, owner); } } private static void EnqueueSlotIfActive(Queue queue, int slot) { if (queue != null && (Object)(object)GetActivePlayerBySlot(slot) != (Object)null) { queue.Enqueue(slot); } } private static PlayerFarming GetActivePlayerBySlot(int slot) { if (PlayerFarming.players == null) { return null; } for (int i = 0; i < PlayerFarming.players.Count; i++) { PlayerFarming val = PlayerFarming.players[i]; if (!((Object)(object)val == (Object)null) && val.playerID == slot && (PlayerFarming.playersCount <= 0 || val.playerID < PlayerFarming.playersCount) && !((Object)(object)val.state == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Component)val).gameObject.activeInHierarchy && HasUsableInput(val)) { return val; } } return null; } private static int GetPreferredVanillaOwnerSlot(PlayerFarming directStarter) { if ((Object)(object)directStarter != (Object)null && directStarter.playerID == 1) { return 1; } if ((Object)(object)GetActivePlayerBySlot(0) != (Object)null) { return 0; } return 1; } private static PlayerFarming ResolvePlayerFromState(StateMachine state) { if ((Object)(object)state == (Object)null) { return null; } PlayerFarming component = ((Component)state).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } try { if ((Object)(object)((Component)state).gameObject != (Object)null) { return PlayerFarming.GetPlayerFarmingComponent(((Component)state).gameObject); } } catch { } return PlayerFarming.Instance; } private static PlayerFarming GetTrackedTarotOwner(Interaction_Tarot interaction) { if ((Object)(object)interaction == (Object)null) { return null; } if (TarotOwnerByInstance.TryGetValue(((Object)interaction).GetInstanceID(), out var value) && (Object)(object)value != (Object)null) { return value; } value = TryResolveInteractionPlayer(interaction); if ((Object)(object)value != (Object)null) { TarotOwnerByInstance[((Object)interaction).GetInstanceID()] = value; } return value; } private static PlayerFarming GetTrackedShrineTarotOwner(Shrines shrine) { if ((Object)(object)shrine == (Object)null) { return null; } int instanceID = ((Object)shrine).GetInstanceID(); if (ShrineTarotOwnerByInstance.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null) { return value; } value = TryResolveInteractionPlayer(shrine); if ((Object)(object)value != (Object)null) { ShrineTarotOwnerByInstance[instanceID] = value; } return value; } private static void SetInteractionContext(object interaction, PlayerFarming player, StateMachine state) { if (interaction != null) { if ((Object)(object)player != (Object)null) { TrySetInteractionPlayer(interaction, player); } if ((Object)(object)state != (Object)null) { TrySetInteractionState(interaction, state); } Interaction_Tarot val = (Interaction_Tarot)((interaction is Interaction_Tarot) ? interaction : null); if ((Object)(object)val != (Object)null && (Object)(object)player != (Object)null) { TarotOwnerByInstance[((Object)val).GetInstanceID()] = player; } Interaction_TarotCard val2 = (Interaction_TarotCard)((interaction is Interaction_TarotCard) ? interaction : null); if ((Object)(object)val2 != (Object)null && (Object)(object)player != (Object)null) { TarotCardOwnerByInstance[((Object)val2).GetInstanceID()] = player; } Shrines val3 = (Shrines)((interaction is Shrines) ? interaction : null); if ((Object)(object)val3 != (Object)null && (Object)(object)player != (Object)null) { ShrineTarotOwnerByInstance[((Object)val3).GetInstanceID()] = player; } } } private static void CleanupInteractionState(int interactionId) { TarotOwnerByInstance.Remove(interactionId); PendingTarotQueueByInstance.Remove(interactionId); WarnedSuppressedDiscardByInstance.Remove(interactionId); } private static void CleanupShrineTarotState(int interactionId) { ShrineTarotOwnerByInstance.Remove(interactionId); PendingShrineTarotQueueByInstance.Remove(interactionId); WarnedSuppressedShrineDiscardByInstance.Remove(interactionId); } private static IEnumerator SuppressedDelayRoutine(float delay) { yield return (object)new WaitForSeconds(0.2f + delay); } private static bool HasUsableInput(PlayerFarming player) { if ((Object)(object)player == (Object)null) { return false; } try { if (player.isLamb) { return true; } if (player.rewiredPlayer == null || player.rewiredPlayer.controllers == null) { return false; } return player.rewiredPlayer.controllers.hasKeyboard || player.rewiredPlayer.controllers.joystickCount > 0; } catch { return true; } } private static void TrySetAllowedInputPlayer(PlayerFarming player) { if ((Object)(object)player == (Object)null) { return; } try { UINavigatorNew instance = MonoSingleton.Instance; if (!((Object)(object)instance == (Object)null)) { instance.AllowInputOnlyFromPlayer = player; instance.TemporarilyAllowInputOnlyFromAnyPlayer = false; } } catch { } } private static bool SafeMoveNext(IEnumerator iterator) { if (iterator == null) { return false; } try { return iterator.MoveNext(); } catch (Exception ex) { TarotAddonPlugin.Log.LogWarning((object)("[Tarot] Coroutine iteration failed: " + ex.Message)); return false; } } private static T TryGetField(object instance, string fieldName) where T : class { if (instance == null || string.IsNullOrEmpty(fieldName)) { return null; } try { return Traverse.Create(instance).Field(fieldName).GetValue() as T; } catch { return null; } } private static T TryGetProperty(object instance, string propertyName) where T : class { if (instance == null || string.IsNullOrEmpty(propertyName)) { return null; } try { return Traverse.Create(instance).Property(propertyName, (object[])null).GetValue() as T; } catch { return null; } } private static bool TrySetField(object instance, string fieldName, object value) { if (instance == null || string.IsNullOrEmpty(fieldName)) { return false; } try { Traverse.Create(instance).Field(fieldName).SetValue(value); return true; } catch { return false; } } private static bool TrySetProperty(object instance, string propertyName, object value) { if (instance == null || string.IsNullOrEmpty(propertyName)) { return false; } try { Traverse.Create(instance).Property(propertyName, (object[])null).SetValue(value); return true; } catch { return false; } } private static PlayerFarming TryResolveInteractionPlayer(object interaction) { if (interaction == null) { return null; } PlayerFarming val = TryGetProperty(interaction, "playerFarming"); if ((Object)(object)val != (Object)null) { return val; } val = TryGetField(interaction, "playerFarming"); if ((Object)(object)val != (Object)null) { return val; } val = TryGetField(interaction, "_playerFarming"); if ((Object)(object)val != (Object)null) { return val; } return TryGetField(interaction, "k__BackingField"); } private static StateMachine TryResolveInteractionState(object interaction) { if (interaction == null) { return null; } StateMachine val = TryGetProperty(interaction, "state"); if ((Object)(object)val != (Object)null) { return val; } val = TryGetField(interaction, "state"); if ((Object)(object)val != (Object)null) { return val; } val = TryGetField(interaction, "_state"); if ((Object)(object)val != (Object)null) { return val; } return TryGetField(interaction, "k__BackingField"); } private static void TrySetInteractionPlayer(object interaction, PlayerFarming player) { if (interaction != null && !TrySetProperty(interaction, "playerFarming", player) && !TrySetField(interaction, "playerFarming", player) && !TrySetField(interaction, "_playerFarming", player)) { TrySetField(interaction, "k__BackingField", player); } } private static void TrySetInteractionState(object interaction, StateMachine state) { if (interaction != null && !TrySetProperty(interaction, "state", state) && !TrySetField(interaction, "state", state) && !TrySetField(interaction, "_state", state)) { TrySetField(interaction, "k__BackingField", state); } } }