Decompiled source of CampfireCards v0.9.6
plugins/CampfireCards/CampfireCards.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.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CampfireCards.Abilities; using CampfireCards.Art; using CampfireCards.Cards; using CampfireCards.Core; using CampfireCards.Generated; using CampfireCards.Net; using CampfireCards.Ui; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak; using Peak.Afflictions; using Photon.Pun; using Photon.Realtime; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.TextCore; using UnityEngine.TextCore.LowLevel; using UnityEngine.UI; using Zorro.ControllerSupport; using Zorro.Core; using Zorro.Core.Serizalization; [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("NotNic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.9.6.0")] [assembly: AssemblyInformationalVersion("0.9.6+7b7686e8771bba6e5a08ae05045713fcaa8edb84")] [assembly: AssemblyProduct("Campfire Cards")] [assembly: AssemblyTitle("CampfireCards")] [assembly: AssemblyVersion("0.9.6.0")] [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 CampfireCards { public static class Controls { public enum Act { BloodBattery, SecondWind, EmergencyPurge, SafetyNet, BuildScreen, ScavengerFood, ScavengerLuggage, ScavengerMisc, BugReport } public const string Auto = "auto"; public const string None = "none"; private static readonly string[] Candidates = new string[7] { "<Gamepad>/dpad/up", "<Gamepad>/dpad/down", "<Gamepad>/dpad/left", "<Gamepad>/dpad/right", "<Gamepad>/select", "<Gamepad>/leftStickPress", "<Gamepad>/rightStickPress" }; private static readonly string[] NotGamepad = new string[5] { "<keyboard>", "<mouse>", "<pointer>", "<touchscreen>", "<pen>" }; private static InputAction[] _pad; private static bool _resolved; private static bool _watching; public static bool UsingGamepad { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 try { return (int)InputHandler.GetCurrentUsedInputScheme() == 1; } catch { return false; } } } public static Act? ActOf(string ability) { return ability switch { "BloodBattery" => Act.BloodBattery, "SecondWind" => Act.SecondWind, "EmergencyPurge" => Act.EmergencyPurge, "SafetyNet" => Act.SafetyNet, _ => null, }; } public static bool SharesButton(Act a, Act b) { //IL_001b: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (a == b) { return true; } ConfigEntry<Key> val = KeyOf(a); ConfigEntry<Key> val2 = KeyOf(b); if (val != null && val2 != null && (int)val.Value != 0 && val.Value == val2.Value) { return true; } InputAction val3 = PadAction(a); InputAction val4 = PadAction(b); if (val3 != null && val4 != null) { InputBinding val5 = val3.bindings[0]; string text = Control(((InputBinding)(ref val5)).effectivePath); val5 = val4.bindings[0]; return text == Control(((InputBinding)(ref val5)).effectivePath); } return false; } public static bool WasPressed(Act act) { if (KeyPressed(KeyOf(act))) { return true; } InputAction val = PadAction(act); if (val != null) { return val.WasPressedThisFrame(); } return false; } public static bool ProducesText(Act act) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 ConfigEntry<Key> val = KeyOf(act); if (val == null || (int)val.Value == 0) { return false; } Key value = val.Value; if ((int)value < 1 || (int)value > 50) { if ((int)value >= 77) { return (int)value <= 93; } return false; } return true; } public static bool IsHeld(Act act) { if (KeyHeld(KeyOf(act))) { return true; } InputAction val = PadAction(act); if (val != null) { return val.IsPressed(); } return false; } public static string Label(Act act) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (UsingGamepad) { InputAction val = PadAction(act); if (val != null) { try { InputBinding val2 = val.bindings[0]; return InputControlPath.ToHumanReadableString(((InputBinding)(ref val2)).effectivePath, (HumanReadableStringOptions)2, (InputControl)null); } catch { } } } ConfigEntry<Key> val3 = KeyOf(act); if (val3 == null || (int)val3.Value == 0) { return "?"; } return ((object)val3.Value/*cast due to .constrained prefix*/).ToString(); } private static ConfigEntry<Key> KeyOf(Act act) { return (ConfigEntry<Key>)(act switch { Act.BloodBattery => Plugin.BloodBatteryKey, Act.SecondWind => Plugin.SecondWindKey, Act.EmergencyPurge => Plugin.EmergencyPurgeKey, Act.SafetyNet => Plugin.SafetyNetKey, Act.ScavengerFood => Plugin.ScavengerFoodKey, Act.ScavengerLuggage => Plugin.ScavengerLuggageKey, Act.ScavengerMisc => Plugin.ScavengerMiscKey, Act.BugReport => Plugin.BugReportKey, _ => Plugin.BuildScreenKey, }); } private static ConfigEntry<string> PadOf(Act act) { return (ConfigEntry<string>)(act switch { Act.BloodBattery => Plugin.BloodBatteryPad, Act.SecondWind => Plugin.SecondWindPad, Act.EmergencyPurge => Plugin.EmergencyPurgePad, Act.SafetyNet => Plugin.SafetyNetPad, Act.ScavengerFood => Plugin.ScavengerFoodPad, Act.ScavengerLuggage => Plugin.ScavengerLuggagePad, Act.ScavengerMisc => Plugin.ScavengerMiscPad, Act.BugReport => Plugin.BugReportPad, _ => Plugin.BuildScreenPad, }); } private static bool KeyPressed(ConfigEntry<Key> key) { //IL_000d: 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) Keyboard current = Keyboard.current; if (current == null || key == null || (int)key.Value == 0) { return false; } try { KeyControl val = current[key.Value]; return val != null && ((ButtonControl)val).wasPressedThisFrame; } catch { return false; } } private static bool KeyHeld(ConfigEntry<Key> key) { //IL_000d: 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) Keyboard current = Keyboard.current; if (current == null || key == null || (int)key.Value == 0) { return false; } try { KeyControl val = current[key.Value]; return val != null && ((ButtonControl)val).isPressed; } catch { return false; } } private static InputAction PadAction(Act act) { Resolve(); if (_pad == null) { return null; } return _pad[(int)act]; } private static void Resolve() { //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) if (_resolved) { return; } InputActionAsset val = null; try { val = InputSystem.actions; } catch { } if ((Object)(object)val == (Object)null) { return; } _resolved = true; WatchRebinds(); Release(); Act[] array = (Act[])Enum.GetValues(typeof(Act)); string[] array2 = new string[array.Length]; HashSet<string> hashSet = GameplayControls(val); HashSet<string> hashSet2 = new HashSet<string>(hashSet); Act[] array3 = array; foreach (Act act in array3) { ConfigEntry<string> val2 = PadOf(act); string text = (array2[(int)act] = ((val2 != null && val2.Value != null) ? val2.Value.Trim() : "auto")); if (!IsAuto(text) && !IsNone(text)) { hashSet2.Add(Control(text)); } } _pad = (InputAction[])(object)new InputAction[array.Length]; array3 = array; for (int i = 0; i < array3.Length; i++) { Act act2 = array3[i]; string text2 = array2[(int)act2]; string text3 = null; if (IsNone(text2)) { continue; } if (IsAuto(text2)) { string[] candidates = Candidates; foreach (string text4 in candidates) { if (!IsUsed(hashSet2, text4)) { text3 = text4; break; } } if (text3 == null) { Plugin.Log.LogWarning((object)$"No free controller button for {act2}: every candidate is used. Set Keys.{act2}Gamepad to a button path, for example <Gamepad>/dpad/left."); continue; } hashSet2.Add(Control(text3)); } else { text3 = text2; if (IsUsed(hashSet, text3)) { Plugin.Log.LogWarning((object)$"Keys.{act2}Gamepad ({text3}) is also bound to a PEAK action; both will fire."); } } try { InputAction val3 = new InputAction("CampfireCards_" + act2, (InputActionType)1, text3, (string)null, (string)null, (string)null); val3.Enable(); if (val3.controls.Count == 0 && Gamepad.all.Count > 0) { Plugin.Log.LogWarning((object)$"Keys.{act2}Gamepad ({text3}) matches no button on the connected controller. Check the path, for example <Gamepad>/dpad/left."); } _pad[(int)act2] = val3; Plugin.Log.LogInfo((object)$"Controller button for {act2}: {text3}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Keys.{act2}Gamepad ({text3}) is not a valid button path: {ex.Message}"); } } } private static bool IsAuto(string w) { return w.Equals("auto", StringComparison.OrdinalIgnoreCase); } private static bool IsNone(string w) { if (w.Length != 0) { return w.Equals("none", StringComparison.OrdinalIgnoreCase); } return true; } private static void Release() { if (_pad == null) { return; } InputAction[] pad = _pad; foreach (InputAction val in pad) { if (val != null) { val.Disable(); val.Dispose(); } } _pad = null; } private static void WatchRebinds() { if (_watching) { return; } _watching = true; InputSystem.onActionChange += delegate(object obj, InputActionChange change) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)change == 8) { InputActionAsset val = null; try { val = InputSystem.actions; } catch { } if (!((Object)(object)val == (Object)null)) { if (obj != val) { InputActionMap val2 = (InputActionMap)((obj is InputActionMap) ? obj : null); if (val2 == null || !((Object)(object)val2.asset == (Object)(object)val)) { InputAction val3 = (InputAction)((obj is InputAction) ? obj : null); if (val3 == null || val3.actionMap == null || !((Object)(object)val3.actionMap.asset == (Object)(object)val)) { return; } } } _resolved = false; } } }; } private static HashSet<string> GameplayControls(InputActionAsset asset) { //IL_0007: 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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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) HashSet<string> hashSet = new HashSet<string>(); Enumerator<InputActionMap> enumerator = asset.actionMaps.GetEnumerator(); try { while (enumerator.MoveNext()) { InputActionMap current = enumerator.Current; if (string.Equals(current.name, "UI", StringComparison.OrdinalIgnoreCase)) { continue; } Enumerator<InputAction> enumerator2 = current.actions.GetEnumerator(); try { while (enumerator2.MoveNext()) { InputAction current2 = enumerator2.Current; if (current2.name.StartsWith("UI", StringComparison.Ordinal) || current2.name.StartsWith("Navigate", StringComparison.Ordinal)) { continue; } Enumerator<InputBinding> enumerator3 = current2.bindings.GetEnumerator(); try { while (enumerator3.MoveNext()) { InputBinding current3 = enumerator3.Current; if (((InputBinding)(ref current3)).isComposite) { continue; } string effectivePath = ((InputBinding)(ref current3)).effectivePath; if (!string.IsNullOrEmpty(effectivePath) && effectivePath[0] == '<') { int num = effectivePath.IndexOf('>'); if (num >= 0 && Array.IndexOf(NotGamepad, effectivePath.Substring(0, num + 1).ToLowerInvariant()) < 0) { hashSet.Add(Control(effectivePath)); } } } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } return hashSet; } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } private static bool IsUsed(HashSet<string> used, string path) { string text = Control(path); for (int num = text.Length; num > 0; num = text.LastIndexOf('/', num - 1)) { if (used.Contains(text.Substring(0, num))) { return true; } } return false; } private static string Control(string path) { int num = path.IndexOf('/'); return ((num >= 0) ? path.Substring(num + 1) : path).ToLowerInvariant(); } } public static class RunState { public static bool OnIsland; public static bool RunStarted; public static bool SentOpeningArrival; public static float GroundedSince = -1f; public static readonly HashSet<Campfire> ArrivedFires = new HashSet<Campfire>(); public static void Reset() { RunStarted = false; SentOpeningArrival = false; GroundedSince = -1f; ArrivedFires.Clear(); Effects.Reset(); Hooks.ResetStatusCarries(); Hooks.ResetEndGameHold(); PickSession.Reset(); Ability_EternalCampfire.Arbiter.Reset(); NetHandlers.Reset(); Hooks.ResetRunTracking(); Hud.ClearMarkers(); DeckScreen.HideIfOpen(); BugReportScreen.HideIfOpen(); } public static bool IsGameplayScene(string name) { if (name != null) { if (!name.Contains("Island")) { return name.Contains("Level_"); } return true; } return false; } } public static class Hooks { private sealed class ItemUse { public Item Item; public int Frame; public bool Food; public bool Cooked; public bool Curative; public float Hunger; public float InjuryBefore; public readonly HashSet<STATUSTYPE> Cured = new HashSet<STATUSTYPE>(); } private sealed class BarCapture { public RectTransform Segments; public float SegmentsRight; public RectTransform Overflow; public float OverflowX; public float FrameWidth; public bool Moved; } [CompilerGenerated] private static class <>O { public static Action<Character> <0>__OnCharacterRegistered; public static UnityAction<Scene, LoadSceneMode> <1>__OnSceneLoaded; public static WillRenderCanvases <2>__ApplyPendingBarFrame; public static Action<EventData> <3>__OnPhotonEvent; } private static float _nextArrivalCheck; private static float _nextAbilityBar; private static bool _photonSubscribed; private static bool? _tfaPresent; private static readonly Dictionary<Campfire, byte> _fireKeys = new Dictionary<Campfire, byte>(); private static int _chainKeysTaken; internal const byte ChainKeyFirst = 200; internal const int ChainKeyRange = 50; private static bool _overlayModsChecked; private static readonly HashSet<int> _unreadableFrom = new HashSet<int>(); private static bool _wasHost; private static int _lastSegmentNumber = int.MinValue; private static readonly FieldRef<ItemActionBase, Item> ActionItem = AccessTools.FieldRefAccess<ItemActionBase, Item>("item"); private static readonly List<ItemUse> _batches = new List<ItemUse>(); private static readonly string[] MedicalItemNames = new string[10] { "Bandages", "FirstAidKit", "Antidote", "Cure-All", "MedicinalRoot", "Mandrake_Hidden", "AloeVera", "Heat Pack", "Amulet_Healing", "HealingDart Variant" }; private static HashSet<ushort> _medicalIds; private static readonly ItemTransaction _lunch = new ItemTransaction(); public const int LockedPocket = 2; private static readonly Dictionary<byte, Campfire> _litFires = new Dictionary<byte, Campfire>(); private static readonly SpawnLedger _spawns = new SpawnLedger(); private const float MaxSpawnDistance = 7f; private static readonly FieldRef<CharacterClimbing, Character> ClimbingCharacter = AccessTools.FieldRefAccess<CharacterClimbing, Character>("character"); private static readonly FieldRef<CharacterRopeHandling, Character> RopeCharacter = AccessTools.FieldRefAccess<CharacterRopeHandling, Character>("character"); private static readonly FieldRef<CharacterVineClimbing, Character> VineCharacter = AccessTools.FieldRefAccess<CharacterVineClimbing, Character>("character"); private static readonly FieldRef<CharacterGrabbing, Character> GrabbingCharacter = AccessTools.FieldRefAccess<CharacterGrabbing, Character>("character"); private static readonly FieldRef<CharacterMovement, Character> MovementCharacter = AccessTools.FieldRefAccess<CharacterMovement, Character>("character"); [ThreadStatic] private static Character _climbCtx; [ThreadStatic] private static int _climbDepth; [ThreadStatic] private static float _slideBefore; [ThreadStatic] private static bool _slideTracked; private static Character _pullLatchHelper; private static float _pullLatchExpire; private static readonly Action<Character, Vector3, float> DragTowards = AccessTools.MethodDelegate<Action<Character, Vector3, float>>(AccessTools.Method(typeof(Character), "DragTowards", (Type[])null, (Type[])null), (object)null, true); private static readonly Action<Character> LimitFalling = AccessTools.MethodDelegate<Action<Character>>(AccessTools.Method(typeof(Character), "LimitFalling", (Type[])null, (Type[])null), (object)null, true); private static readonly Action<Character> UnStick = AccessTools.MethodDelegate<Action<Character>>(AccessTools.Method(typeof(Character), "UnStick", (Type[])null, (Type[])null), (object)null, true); [ThreadStatic] private static int _dynamiteSpawnDepth; [ThreadStatic] private static bool _dynamiteBlast; private static int _lastFeederActor = int.MinValue; private static float _lastFedTime; private static float _endGameHoldUntil; private static Character _endGameRecheck; private static readonly FieldRef<CharacterHeatEmission, Character> HeatEmissionCharacter = AccessTools.FieldRefAccess<CharacterHeatEmission, Character>("character"); private static readonly FieldRef<CharacterHeatEmission, float> HeatEmissionCounter = AccessTools.FieldRefAccess<CharacterHeatEmission, float>("counter"); private static readonly FieldRef<CharacterAfflictions, bool> AfflictionsInAirport = AccessTools.FieldRefAccess<CharacterAfflictions, bool>("m_inAirport"); private static readonly FieldRef<CharacterData, bool> NativeInvincible = AccessTools.FieldRefAccess<CharacterData, bool>("isInvincible"); private static readonly FieldRef<CharacterAfflictions, float[]> IncrementalStatuses = AccessTools.FieldRefAccess<CharacterAfflictions, float[]>("currentIncrementalStatuses"); private static readonly FieldRef<CharacterAfflictions, float[]> DecrementalStatuses = AccessTools.FieldRefAccess<CharacterAfflictions, float[]>("currentDecrementalStatuses"); private static readonly int StatusCount = Enum.GetValues(typeof(STATUSTYPE)).Length; private static readonly StatusCarry AddCarry = new StatusCarry(StatusCount); private static readonly StatusCarry SubCarry = new StatusCarry(StatusCount); private static float _petrifyCarry; [ThreadStatic] internal static int _itemActionDepth; [ThreadStatic] internal static bool _itemScaled; [ThreadStatic] private static int _fallDepth; [ThreadStatic] private static Character _heatEmitter; [ThreadStatic] private static Character _regenChar; private static readonly Dictionary<int, float> _shareOwed = new Dictionary<int, float>(); private static float _injuryCommitted; private static readonly Action<Character, Vector3, Vector3, float> AddForceAt = AccessTools.MethodDelegate<Action<Character, Vector3, Vector3, float>>(AccessTools.Method(typeof(Character), "AddForceAtPosition", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef<StatusFieldBase, float> FieldLastEntered = AccessTools.FieldRefAccess<StatusFieldBase, float>("lastEnteredTime"); private static readonly FieldRef<StatusFieldBase, bool> FieldInflicting = AccessTools.FieldRefAccess<StatusFieldBase, bool>("inflicting"); private static readonly FieldRef<StatusFieldBase, bool> FieldInField = AccessTools.FieldRefAccess<StatusFieldBase, bool>("characterInField"); private static readonly Dictionary<int, BarCapture> _barCaptures = new Dictionary<int, BarCapture>(); private static StaminaBar _barToStyle; private static readonly ThornsLedger _thorns = new ThornsLedger(); internal static bool TfaPresent { get { if (!_tfaPresent.HasValue) { try { _tfaPresent = Chainloader.PluginInfos.ContainsKey("com.CptPICHU.peak.truefinalascent"); } catch { _tfaPresent = false; } } return _tfaPresent.Value; } } public static float PendingInjuryCarry => AddCarry.Of(0); public static void Subscribe() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_007f: 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_008a: Expected O, but got Unknown PlayerHandler.CharacterRegistered = (Action<Character>)Delegate.Combine(PlayerHandler.CharacterRegistered, new Action<Character>(OnCharacterRegistered)); SceneManager.sceneLoaded += OnSceneLoaded; object obj = <>O.<2>__ApplyPendingBarFrame; if (obj == null) { WillRenderCanvases val = ApplyPendingBarFrame; <>O.<2>__ApplyPendingBarFrame = val; obj = (object)val; } Canvas.willRenderCanvases -= (WillRenderCanvases)obj; object obj2 = <>O.<2>__ApplyPendingBarFrame; if (obj2 == null) { WillRenderCanvases val2 = ApplyPendingBarFrame; <>O.<2>__ApplyPendingBarFrame = val2; obj2 = (object)val2; } Canvas.willRenderCanvases += (WillRenderCanvases)obj2; SubscribePhoton(); } private static void SubscribePhoton() { if (!_photonSubscribed) { LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient; if (networkingClient != null) { networkingClient.EventReceived += OnPhotonEvent; _photonSubscribed = true; } } } private static IEnumerator ResubscribeNextFrame() { yield return null; SubscribePhoton(); } public static void ResetRunTracking() { _lastFeederActor = int.MinValue; _fallDepth = 0; _climbDepth = 0; _climbCtx = null; _batches.Clear(); _thorns.Reset(); _lunch.Reset(); _dynamiteSpawnDepth = 0; _dynamiteBlast = false; _lastSegmentNumber = int.MinValue; _fireKeys.Clear(); _chainKeysTaken = 0; ResetCampfireSpawns(); } public static void OnRunStarted() { RunState.Reset(); RunState.RunStarted = true; RunState.OnIsland = true; LocalCards.OnRunStarted(Environment.TickCount ^ (NetSend.LocalActor * 7919)); RunMemoryFile.OnRunStarted(LocalCards.RunSeed); PickSession.OnRunStarted(); Hud.Ensure(); _wasHost = NetSend.IsHost; RecordRoster(); if (!NetSend.IsHost) { NetSend.Raise(NetHandlers.MakeHello(), (ReceiverGroup)0); } Plugin.Log.LogInfo((object)$"Run started. Host={NetSend.IsHost} actor={NetSend.LocalActor} solo={NetSend.IsSolo} deck={Deck.Count} cards"); WarnOverlayMods(); } public static void OnRunEnded() { RunState.Reset(); RunMemoryFile.OnRunEnded(); Hud.CloseAll(); } public static void OnCampfireLitPrefix(Campfire __instance, bool updateSegment, out FireState __state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected I4, but got Unknown __state = (FireState)(int)__instance.state; if ((int)__state != 1 && RunState.RunStarted) { if (TfaPresent) { PickSession.CapturePreLitEligibility(); } if (updateSegment) { PickSession.SnapshotCampfireEligibility(FireKey(__instance)); } } } public static void OnCampfireLit(Campfire __instance, bool updateSegment, float burningFor, FireState __state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0107: Unknown result type (might be due to invalid IL or missing references) if ((int)__state == 1 || !RunState.RunStarted) { return; } Character localCharacter = Character.localCharacter; byte b = FireKey(__instance); byte b2 = b; bool flag = false; if (!updateSegment) { if (!TfaPresent) { return; } bool flag2 = burningFor <= 0.01f && PhotonNetwork.Time - PickSession.RunStartTime > 20.0; Plugin.Log.LogInfo((object)($"Campfire lit without a segment advance (burningFor {burningFor:0.##}): " + (flag2 ? "chained-run biome fire" : "sync relight, ignored"))); if (!flag2) { return; } flag = true; } else if (TfaPresent && PickSession.SegmentUsed(b)) { flag = true; } bool flag3 = true; if (flag) { if (!PollBiomeNow(localCharacter) && (Object)(object)localCharacter != (Object)null) { LocalCards.OnChainBoundary(localCharacter); } if (NetSend.IsHost) { int num = TakeFreeChainKey(); if (num < 0) { flag3 = false; Plugin.Log.LogWarning((object)"Chain keys exhausted; this fire deals no cards"); } else { b2 = (byte)num; PickSession.AdoptPreLitEligibility(b2); _fireKeys[__instance] = b2; } } } else { _fireKeys[__instance] = b2; } Plugin.Log.LogInfo((object)$"Campfire lit -> {__instance.advanceToSegment} (key {b2})"); if (NetSend.IsHost) { HostCampfireLit(__instance, b); } if ((Object)(object)localCharacter != (Object)null) { LocalCards.OnCampfireLit(localCharacter, __instance); } if (flag3 && (!TfaPresent || NetSend.IsHost)) { PickSession.RequestSession(1, b2); } } private static void WarnOverlayMods() { if (_overlayModsChecked) { return; } _overlayModsChecked = true; try { foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { string text = ((pluginInfo.Value != null && pluginInfo.Value.Metadata != null) ? pluginInfo.Value.Metadata.Name : null); if (text != null && text.IndexOf("EffectPreview", StringComparison.OrdinalIgnoreCase) >= 0) { Plugin.Log.LogInfo((object)(text + " detected: its stamina-bar overlay may not line up with card-extended stamina bars")); } } } catch { } } internal static byte FireKey(Campfire fire) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)fire != (Object)null && _fireKeys.TryGetValue(fire, out var value)) { return value; } int num = (((Object)(object)fire != (Object)null) ? ((int)fire.advanceToSegment) : 0); return (byte)((num >= 255) ? 254u : ((uint)num)); } private static int TakeFreeChainKey() { for (int i = 0; i < 50; i++) { byte b = (byte)(200 + _chainKeysTaken++ % 50); if (!PickSession.SegmentUsed(b)) { return b; } } return -1; } public static void OnLobbyCreated(SteamLobbyHandler __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) try { CSteamID lobbySteamId = __instance.LobbySteamId; if (((CSteamID)(ref lobbySteamId)).IsValid()) { HostLog.WriteHosting(lobbySteamId.m_SteamID); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("HostLog: " + ex.Message)); } } public static void OnCharacterRegistered(Character c) { if ((Object)(object)c == (Object)null) { return; } try { int actor = NetSend.ActorOf(c); if (c.IsLocal) { if (!NetSend.IsHost && !Effects.HasAnyState) { NetSend.RaiseToMaster(NetHandlers.MakeHello()); NetSend.RaiseToMaster(new StateRequest { modVersion = "0.9.6" }); } } else if (NetSend.IsHost) { PickSession.HostNoteReady(actor, arrived: false); HostAdoptRejoiners(); if (Effects.HasAnyState) { NetSend.RaiseTo(Effects.BuildStateSync(PickSession.SessionId), actor); } if (PickSession.HasMirror) { NetSend.RaiseTo(PickSession.BuildMirror(), actor); } } } catch (Exception ex) { Plugin.Log.LogError((object)("OnCharacterRegistered: " + ex)); } } internal static void HostAdoptRejoiners() { if (!NetSend.IsHost || !RunState.RunStarted) { return; } Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom == null) { return; } List<int> list = new List<int>(); foreach (Player value2 in currentRoom.Players.Values) { list.Add(value2.ActorNumber); } bool flag = false; foreach (Player value3 in currentRoom.Players.Values) { foreach (int item in PickSession.Directory.DepartedTwins(value3.ActorNumber, value3.UserId, list)) { if ((Effects.CardsByActor.TryGetValue(item, out var value) && value.Count > 0) || Effects.Flags(item) != 0 || Effects.Penalties.Count(item) != 0) { Effects.TransferActorState(item, value3.ActorNumber); PickSession.OnActorReplaced(item, value3.ActorNumber); Ability_EternalCampfire.Arbiter.Transfer(item, value3.ActorNumber); _spawns.Transfer(item, value3.ActorNumber); flag = true; Plugin.Log.LogInfo((object)$"Rejoin: moved {Effects.CardsOf(value3.ActorNumber).Count} card(s) back to {NetSend.NameOf(value3.ActorNumber)} (actor {item} -> {value3.ActorNumber})"); } } } if (flag) { NetSend.Raise(Effects.BuildStateSync(PickSession.SessionId), (ReceiverGroup)1); } } private static void RecordRoster() { Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom == null) { return; } List<int> list = new List<int>(); foreach (Player value in currentRoom.Players.Values) { list.Add(value.ActorNumber); } foreach (Player value2 in currentRoom.Players.Values) { foreach (int item in PickSession.Directory.DepartedTwins(value2.ActorNumber, value2.UserId, list)) { PickSession.OnActorReplaced(item, value2.ActorNumber); } PickSession.Directory.Record(value2.ActorNumber, value2.UserId); } } public static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ResetBarCaptures(); if (!(RunState.OnIsland = RunState.IsGameplayScene(((Scene)(ref scene)).name))) { RunState.Reset(); Hud.CloseAll(); } Plugin.Run(ResubscribeNextFrame()); } public static void OnPhotonEvent(EventData e) { try { if (e.Code == 254) { PickSession.OnPlayerLeft(e.Sender); if (NetSend.IsHost) { Ability_EternalCampfire.Arbiter.ForgetVictim(e.Sender); } _unreadableFrom.Remove(e.Sender); } else { if (e.Code < 90 || e.Code > 119 || !(e.CustomData is byte[] data)) { return; } try { NetDispatcher.Dispatch(e.Code, data, e.Sender); return; } catch (Exception ex) when (ex is IOException || ex is InvalidDataException || ex is FormatException) { Plugin.Log.LogWarning((object)$"Net event {e.Code} from actor {e.Sender} could not be read: {ex.Message}"); if (_unreadableFrom.Add(e.Sender)) { Hud.Toast($"Can't read Campfire Cards data from {NetSend.NameOf(e.Sender)}. Everyone needs the same mod version.", warning: true); } return; } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Net event {e.Code}: {arg}"); } } public static void Tick() { _fallDepth = 0; _climbDepth = 0; _climbCtx = null; _itemActionDepth = 0; _itemScaled = false; CardSettings.Current.BenefitStrength = (RunState.OnIsland ? CardSettings.Current.StrengthFor(Ascents.currentAscent) : 1f); if (!RunState.OnIsland) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } Hud.Ensure(); if (!RunState.RunStarted) { return; } if (!_wasHost && NetSend.IsHost) { _wasHost = true; PickSession.HostPromotedSweep(); } RestoreKey(localCharacter); PollBiome(localCharacter); Effects.Recompute(localCharacter); SampleInjuryCapFloor(localCharacter); LocalCards.Tick(localCharacter, Time.deltaTime); FlushItemUses(localCharacter); AbilityKeys(localCharacter); PickSession.HostTick(); DeckScreen.Tick(localCharacter); BugReportScreen.Tick(); TickEndGameHold(); if (Time.unscaledTime >= _nextAbilityBar) { _nextAbilityBar = Time.unscaledTime + 0.2f; Hud.RefreshAbilityBar(localCharacter); PickSession.UpdateBanner(); } if (!(Time.unscaledTime < _nextArrivalCheck)) { _nextArrivalCheck = Time.unscaledTime + 0.25f; RecordRoster(); if (NetSend.IsHost) { HostAdoptRejoiners(); } CheckArrivals(localCharacter); } } private static void PollBiome(Character local) { PollBiomeNow(local); } private static bool PollBiomeNow(Character local) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown if ((Object)(object)local == (Object)null) { return false; } int num; try { num = (int)MapHandler.CurrentSegmentNumber; } catch { return false; } if (num == _lastSegmentNumber) { return false; } _lastSegmentNumber = num; LocalCards.OnSegmentNumber(local, num); return true; } private static void AbilityKeys(Character local) { bool flag = false; try { flag = (Object)(object)GUIManager.instance != (Object)null && (GUIManager.instance.windowBlockingInput || GUIManager.instance.wheelActive); } catch { } if (flag) { return; } if (!local.data.dead && !local.data.passedOut && !local.data.fullyPassedOut) { HashSet<Controls.Act> hashSet = new HashSet<Controls.Act>(); foreach (Ability item in LocalCards.Manual) { Controls.Act? act = Controls.ActOf(item.Card.Ability); if (!act.HasValue || !hashSet.Add(act.Value) || !Controls.WasPressed(act.Value)) { continue; } List<Ability> list = new List<Ability>(); foreach (Ability item2 in LocalCards.Manual) { Controls.Act? act2 = Controls.ActOf(item2.Card.Ability); if (act2.HasValue && Controls.SharesButton(act.Value, act2.Value)) { list.Add(item2); } } if (list.Count > 1) { Hud.Toast("These abilities share a key. Assign separate keys in the config.", warning: true); break; } try { item.Activate(local); } catch (Exception arg) { Plugin.Log.LogError((object)$"{item.Card.Name} Activate: {arg}"); } } } if (Controls.WasPressed(Controls.Act.BuildScreen)) { DeckScreen.Toggle(local); } if (Controls.WasPressed(Controls.Act.BugReport)) { BugReportScreen.Toggle(); } } public static bool OnUpdatePausedPrefix(GUIManager __instance) { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.input == (Object)null || !localCharacter.input.pauseWasPressed) { return true; } if ((Object)(object)DeckScreen.Instance != (Object)null && ((MenuWindow)DeckScreen.Instance).isOpen) { localCharacter.input.pauseWasPressed = false; DeckScreen.Instance.BackFromInput(); return false; } if (ItemChooser.IsOpen) { localCharacter.input.pauseWasPressed = false; ItemChooser.Instance.HideNow(); return false; } if ((Object)(object)BugReportScreen.Instance != (Object)null && ((MenuWindow)BugReportScreen.Instance).isOpen) { localCharacter.input.pauseWasPressed = false; BugReportScreen.Instance.CloseFromInput(); return false; } return true; } private static void CheckArrivals(Character local) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if (!RunState.SentOpeningArrival) { if (local.data.passedOutOnTheBeach <= 0f && !local.warping && local.data.isGrounded && !local.data.passedOut) { if (RunState.GroundedSince < 0f) { RunState.GroundedSince = Time.unscaledTime; } if (Time.unscaledTime - RunState.GroundedSince >= 2f) { RunState.SentOpeningArrival = true; NetSend.Raise(new Arrival { segment = byte.MaxValue, time = PhotonNetwork.Time }, (ReceiverGroup)0); PickSession.RecordArrival(NetSend.LocalActor, byte.MaxValue, PhotonNetwork.Time); } } else { RunState.GroundedSince = -1f; } } Campfire val = null; try { val = MapHandler.CurrentCampfire; } catch { } if ((Object)(object)val != (Object)null && !val.Lit && !RunState.ArrivedFires.Contains(val)) { float num = ((val.moraleBoostRadius > 0f) ? val.moraleBoostRadius : 15f); if (Vector3.Distance(local.Center, ((Component)val).transform.position) <= num) { byte segment = FireKey(val); RunState.ArrivedFires.Add(val); NetSend.Raise(new Arrival { segment = segment, time = PhotonNetwork.Time }, (ReceiverGroup)0); PickSession.RecordArrival(NetSend.LocalActor, segment, PhotonNetwork.Time); } } } private static void RestoreKey(Character local) { //IL_0013: 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) ConfigEntry<Key> restoreRunKey = Plugin.RestoreRunKey; Keyboard current = Keyboard.current; if (current == null || restoreRunKey == null || (int)restoreRunKey.Value == 0) { return; } bool flag = false; try { flag = (Object)(object)GUIManager.instance != (Object)null && (GUIManager.instance.windowBlockingInput || GUIManager.instance.wheelActive); } catch { } if (flag) { return; } KeyControl val = null; try { val = current[restoreRunKey.Value]; } catch { } if (val != null && ((ButtonControl)val).wasPressedThisFrame) { if (!NetSend.IsHost) { Hud.Toast("Card restore: only the host can restore the run"); } else { RunMemoryFile.RestoreAll(); } } } private static ItemUse Batch(Item item, Character user) { foreach (ItemUse batch in _batches) { if ((Object)(object)batch.Item == (Object)(object)item && batch.Frame == Time.frameCount) { return batch; } } ItemUse itemUse = new ItemUse { Item = item, Frame = Time.frameCount, InjuryBefore = user.refs.afflictions.GetCurrentStatus((STATUSTYPE)0) }; _batches.Add(itemUse); return itemUse; } private static void FlushItemUses(Character local) { for (int num = _batches.Count - 1; num >= 0; num--) { ItemUse itemUse = _batches[num]; if (itemUse.Frame < Time.frameCount) { _batches.RemoveAt(num); if (itemUse.Food) { Plugin.Verbose(string.Format("Ate {0}: cooked={1}, Hunger removed {2:0.#}", ((Object)(object)itemUse.Item != (Object)null) ? itemUse.Item.GetItemName((ItemInstanceData)null) : "?", itemUse.Cooked, itemUse.Hunger * 100f)); } if (itemUse.Food) { LocalCards.OnFood(local, new FoodEvent { Item = itemUse.Item, Cooked = itemUse.Cooked, HungerRemoved = itemUse.Hunger, InjuryBefore = itemUse.InjuryBefore }); } if (itemUse.Curative) { LocalCards.OnCurative(local, new CurativeEvent { Item = itemUse.Item, Cured = itemUse.Cured }); } } } } public static bool IsCooked(Item item) { if ((Object)(object)item == (Object)null) { return false; } try { IntItemData val = default(IntItemData); if (item.data != null && item.data.TryGetDataEntry<IntItemData>((DataEntryKey)1, ref val)) { return val.Value > 0; } return (Object)(object)item.cooking != (Object)null && item.cooking.timesCookedLocal > 0; } catch { return false; } } public static bool IsFood(Item item) { if ((Object)(object)item != (Object)null) { return (Object)(object)((Component)item).GetComponent<Action_RestoreHunger>() != (Object)null; } return false; } public static bool IsCurativeItem(Item item) { if ((Object)(object)item == (Object)null) { return false; } if (_medicalIds == null || _medicalIds.Count == 0) { HashSet<ushort> hashSet = new HashSet<ushort>(); string[] medicalItemNames = MedicalItemNames; Item val = default(Item); for (int i = 0; i < medicalItemNames.Length; i++) { if (ItemDatabase.TryGetItem(medicalItemNames[i], ref val) && (Object)(object)val != (Object)null) { hashSet.Add(val.itemID); } } if (hashSet.Count == 0) { return false; } _medicalIds = hashSet; } return _medicalIds.Contains(item.itemID); } public static void OnRestoreHungerPrefix(Action_RestoreHunger __instance, out float __state) { __state = __instance.restorationAmount; _itemActionDepth++; Item val = ActionItem.Invoke((ItemActionBase)(object)__instance); Character val2 = (((Object)(object)val != (Object)null) ? val.holderCharacter : null); if (Mine(val2)) { bool cooked = IsCooked(val); float num = StatComposites.FoodNutrition(Effects.Local, cooked); if (__state > 0f && Mathf.Abs(num - 1f) > 0.0001f) { __instance.restorationAmount = __state * num; _itemScaled = true; } ItemUse itemUse = Batch(val, val2); itemUse.Food = true; itemUse.Cooked = cooked; itemUse.Hunger += __instance.restorationAmount; } } public static void OnRestoreHunger(Action_RestoreHunger __instance, float __state) { __instance.restorationAmount = __state; if (_itemActionDepth > 0) { _itemActionDepth--; } _itemScaled = false; } public static void OnModifyStatusActionPrefix(Action_ModifyStatus __instance, out float __state) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 //IL_005b: 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) __state = __instance.changeAmount; _itemActionDepth++; if (__state >= 0f) { return; } Item val = ActionItem.Invoke((ItemActionBase)(object)__instance); Character val2 = (((Object)(object)val != (Object)null) ? val.holderCharacter : null); if (!Mine(val2)) { return; } STATUSTYPE statusType = __instance.statusType; if ((int)statusType == 1) { return; } ItemUse itemUse = Batch(val, val2); if ((int)statusType == 0) { float num = Effects.Local[Channel.healReceived]; Character val3 = default(Character); num = ((!val.TryGetFeeder(ref val3) || !((Object)(object)val3 != (Object)null) || !((Object)(object)val3 != (Object)(object)val2)) ? (num * Effects.Local[Channel.healSelfUse]) : (num * Effects.ActorChannel(NetSend.ActorOf(val3), Channel.healGiven))); if (Mathf.Abs(num - 1f) > 0.0001f) { __instance.changeAmount = __state * num; _itemScaled = true; } } if (CurativeSelection.RecordMedicalCure(itemUse.Cured, statusType, (STATUSTYPE)3, (STATUSTYPE)10, IsCurativeItem(val))) { itemUse.Curative = true; } } public static void OnModifyStatusAction(Action_ModifyStatus __instance, float __state) { __instance.changeAmount = __state; if (_itemActionDepth > 0) { _itemActionDepth--; } _itemScaled = false; } public static void OnApplyAfflictionActionPrefix(Action_ApplyAffliction __instance) { Item val = ActionItem.Invoke((ItemActionBase)(object)__instance); Character val2 = (((Object)(object)val != (Object)null) ? val.holderCharacter : null); if (!Mine(val2) || !IsCurativeItem(val)) { return; } ItemUse itemUse = Batch(val, val2); itemUse.Curative = true; if (WarmsCold(__instance.affliction)) { itemUse.Cured.Add((STATUSTYPE)2); } if (__instance.extraAfflictions == null) { return; } Affliction[] extraAfflictions = __instance.extraAfflictions; for (int i = 0; i < extraAfflictions.Length; i++) { if (WarmsCold(extraAfflictions[i])) { itemUse.Cured.Add((STATUSTYPE)2); } } } private static bool WarmsCold(Affliction a) { return a is Affliction_AdjustColdOverTime; } public static void OnHealingGemActionPrefix(Action_HealingGem __instance, out float[] __state) { __state = null; Item val = ActionItem.Invoke((ItemActionBase)(object)__instance); Character val2 = (((Object)(object)val != (Object)null) ? val.holderCharacter : null); if (Mine(val2) && IsCurativeItem(val)) { CharacterAfflictions afflictions = val2.refs.afflictions; __state = new float[StatusCount]; for (int i = 0; i < __state.Length; i++) { __state[i] = afflictions.GetCurrentStatus((STATUSTYPE)i); } } } public static void OnHealingGemAction(Action_HealingGem __instance, float[] __state) { if (__state == null) { return; } Item val = ActionItem.Invoke((ItemActionBase)(object)__instance); Character val2 = (((Object)(object)val != (Object)null) ? val.holderCharacter : null); if (!Mine(val2)) { return; } CharacterAfflictions afflictions = val2.refs.afflictions; ItemUse itemUse = Batch(val, val2); itemUse.Curative = true; for (int i = 0; i < __state.Length; i++) { if (afflictions.GetCurrentStatus((STATUSTYPE)i) < __state[i] - 0.0001f) { itemUse.Cured.Add((STATUSTYPE)i); } } } public static void OnClearAllStatusActionPrefix(Action_ClearAllStatus __instance) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) Item val = ActionItem.Invoke((ItemActionBase)(object)__instance); Character val2 = (((Object)(object)val != (Object)null) ? val.holderCharacter : null); if (!Mine(val2) || !IsCurativeItem(val)) { return; } ItemUse itemUse = Batch(val, val2); itemUse.Curative = true; foreach (STATUSTYPE value in Enum.GetValues(typeof(STATUSTYPE))) { itemUse.Cured.Add(value); } } private static bool LuckyLunchSaves(Item item) { if ((Object)(object)item == (Object)null) { return false; } return _lunch.Decide(((Object)item).GetInstanceID(), Time.frameCount, delegate { if (!Mine(item.holderCharacter) || !IsFood(item)) { return false; } Ability_LuckyLunch ability_LuckyLunch = LocalCards.Get<Ability_LuckyLunch>(); if (ability_LuckyLunch == null) { return false; } bool flag = IsCooked(item); bool flag2 = flag && ability_LuckyLunch.TryUse(); if (!flag) { ability_LuckyLunch.HintUncooked(); } Plugin.Verbose(string.Format("Lucky Lunch: {0} cooked={1} biome={2} -> {3}", item.GetItemName((ItemInstanceData)null), flag, LocalCards.Biome, flag2 ? "kept" : (flag ? "used up (already used this biome)" : "used up (not cooked)"))); return flag2; }); } private static void FireConsumedOnce(Item item) { if ((Object)(object)item != (Object)null && item.OnConsumed != null && _lunch.TryFireEffects(((Object)item).GetInstanceID(), Time.frameCount)) { item.OnConsumed(); } } public static bool OnConsumeDelayedPrefix(Item __instance, bool ignoreActions, ref IEnumerator __result) { if (!LuckyLunchSaves(__instance)) { return true; } __result = KeepItem(__instance, ignoreActions); return false; } private static IEnumerator KeepItem(Item item, bool ignoreActions) { if (!ignoreActions) { FireConsumedOnce(item); } yield return null; if ((Object)(object)item != (Object)null && (Object)(object)item.overrideHolderCharacter != (Object)null && (Object)(object)item.trueHolderCharacter != (Object)(object)item.overrideHolderCharacter) { item.overrideHolderCharacter = null; } } public static bool OnReduceUsesPrefix(Action_ReduceUses __instance) { return !LuckyLunchSaves(ActionItem.Invoke((ItemActionBase)(object)__instance)); } public static bool OnConsumeAndSpawnPrefix(Action_ConsumeAndSpawn __instance) { Item item = ActionItem.Invoke((ItemActionBase)(object)__instance); if (!LuckyLunchSaves(item)) { return true; } FireConsumedOnce(item); return false; } private static bool PocketLocked(Player p) { try { PhotonView photonView = ((MonoBehaviourPun)p).photonView; if ((Object)(object)photonView == (Object)null || photonView.Owner == null) { return false; } return RunState.RunStarted && CardSettings.Current.DrawbacksEnabled && Effects.HasAbility(photonView.Owner.ActorNumber, "PocketTradeoff"); } catch { return false; } } public static bool OnAddItemPrefix(Player __instance, ushort itemID, ref ItemInstanceData instanceData, ref ItemSlot slot, ref bool __result) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient || !PocketLocked(__instance)) { return true; } Item val = default(Item); if (!ItemDatabase.TryGetItem(itemID, ref val) || val is Backpack) { return true; } ItemSlot[] itemSlots = __instance.itemSlots; if (itemSlots == null || itemSlots.Length <= 2 || !itemSlots[2].IsEmpty()) { return true; } for (int i = 0; i < itemSlots.Length; i++) { if (i != 2 && itemSlots[i].IsEmpty()) { return true; } } if (instanceData == null) { instanceData = new ItemInstanceData(Guid.NewGuid()); ItemInstanceDataHandler.AddInstanceData(instanceData); } Character character = __instance.character; if (__instance.tempFullSlot.IsEmpty() && (Object)(object)character != (Object)null && !character.data.isClimbingAnything) { __instance.tempFullSlot.SetItem(val, instanceData); slot = __instance.tempFullSlot; byte[] array = IBinarySerializable.ToManagedArray<InventorySyncData>(new InventorySyncData(__instance.itemSlots, __instance.backpackSlot, __instance.tempFullSlot)); ((MonoBehaviourPun)__instance).photonView.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2] { array, false }); __result = true; return false; } slot = null; __result = false; return false; } public static bool OnHasEmptySlotPrefix(Player __instance, ushort itemID, ref bool __result) { if (!PocketLocked(__instance)) { return true; } Item val = default(Item); if (!ItemDatabase.TryGetItem(itemID, ref val) || val is Backpack) { return true; } ItemSlot[] itemSlots = __instance.itemSlots; for (int i = 0; i < itemSlots.Length; i++) { if (i != 2 && itemSlots[i].IsEmpty()) { __result = true; return false; } } __result = __instance.tempFullSlot.IsEmpty(); return false; } private static void ResetCampfireSpawns() { _litFires.Clear(); _spawns.Reset(); } private static void HostCampfireLit(Campfire fire, byte raw) { byte b = FireKey(fire); _litFires[b] = fire; _spawns.FireLit(b); if (raw != b) { _litFires[raw] = fire; _spawns.ForgetFire(raw); _spawns.FireLit(raw); } } public static void HostSpawnItem(SpawnItem m, int sender) { if (!PhotonNetwork.IsMasterClient && !PhotonNetwork.OfflineMode) { return; } bool ownsCardForItem = false; bool flag = false; byte b = 0; foreach (byte item in Effects.CardsOf(sender)) { CardDef cardDef = CardSettings.Current.Card(item); if (cardDef != null) { int num = Mathf.RoundToInt(CardSettings.Current.Param(cardDef, "item", -1f)); if (cardDef.Ability == "CampfireSpawn" && num == m.item) { ownsCardForItem = true; flag = true; break; } if (cardDef.Ability == "BoneBook" && num == m.item) { b = 8; ownsCardForItem = (Effects.Flags(sender) & b) == 0; break; } if (cardDef.Ability == "MythicChoice" && m.item < CardTable.SpawnItems.Length && Array.IndexOf(CardTable.MythicItems, CardTable.SpawnItems[m.item]) >= 0) { b = 4; ownsCardForItem = (Effects.Flags(sender) & b) == 0; break; } } } if (m.item >= CardTable.SpawnItems.Length) { ownsCardForItem = false; } SpawnVerdict spawnVerdict = _spawns.TryClaim(sender, m.item, m.segment, ownsCardForItem); if (spawnVerdict != SpawnVerdict.Ok) { Plugin.Log.LogWarning((object)$"Refused item {m.item} for actor {sender} at fire {m.segment}: {spawnVerdict}"); return; } if (!_litFires.TryGetValue(m.segment, out var value) || (Object)(object)value == (Object)null) { Plugin.Log.LogWarning((object)$"Item {m.item}: fire {m.segment} is gone"); return; } Item obj = SpawnByFire(value, CardTable.SpawnItems[m.item], sender * 3 + m.item); if ((Object)(object)obj != (Object)null && b != 0) { Effects.SetFlag(sender, b, on: true); NetSend.Raise(new CardRewardUsed { actor = sender, flag = b }, (ReceiverGroup)1); } if ((Object)(object)obj != (Object)null && flag) { string text = CarePackageRolls.RandomItemName(foodOnly: true); if (text != null) { SpawnByFire(value, text, sender * 3 + m.item + 101); } string text2 = CarePackageRolls.RandomItemName(foodOnly: false); if (text2 != null) { SpawnByFire(value, text2, sender * 3 + m.item + 202); } } } private static Item SpawnByFire(Campfire fire, string name, int salt) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0088: 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_0093: 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_009d: Unknown result type (might be due to invalid IL or missing references) Item val = default(Item); if (!ItemDatabase.TryGetItem(name, ref val)) { Plugin.Log.LogWarning((object)("Unknown item prefab " + name)); return null; } if (!SpawnSpot(fire, salt, out var pos)) { Plugin.Log.LogWarning((object)("Item " + name + ": no room next to the fire")); return null; } GameObject val2 = PhotonNetwork.InstantiateItemRoom(name, pos + Vector3.up * 0.25f, Quaternion.identity, true); Item val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Item>() : null); if ((Object)(object)val3 != (Object)null) { val3.SetKinematicNetworked(true, pos + Vector3.up * 0.25f, Quaternion.identity); } Plugin.Verbose($"Spawned {name} at {pos}"); return val3; } private static bool SpawnSpot(Campfire fire, int salt, out Vector3 pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) Vector3 position = ((Component)fire).transform.position; if (!SafeSpot.NearCampfire(fire, salt, out pos, out var _)) { if (!SafeSpot.Near(position, 2.5f, 6f, out pos)) { return false; } pos -= Vector3.up * 1f; } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(pos.x - position.x, pos.z - position.z); if (((Vector2)(ref val)).magnitude <= 7f) { return Mathf.Abs(pos.y - position.y) <= 4f; } return false; } private static void EnterClimb(Character c) { if (!((Object)(object)c == (Object)null)) { _climbCtx = c; _climbDepth++; } } private static void ExitClimb() { if (--_climbDepth <= 0) { _climbDepth = 0; _climbCtx = null; } } public static void OnWallClimbContextPrefix(CharacterClimbing __instance) { EnterClimb(ClimbingCharacter.Invoke(__instance)); } public static void OnWallClimbContext(CharacterClimbing __instance) { ExitClimb(); } public static void OnRopeClimbContextPrefix(CharacterRopeHandling __instance) { EnterClimb(RopeCharacter.Invoke(__instance)); } public static void OnRopeClimbContext(CharacterRopeHandling __instance) { ExitClimb(); } public static void OnVineClimbContextPrefix(CharacterVineClimbing __instance) { EnterClimb(VineCharacter.Invoke(__instance)); } public static void OnVineClimbContext(CharacterVineClimbing __instance) { ExitClimb(); } public static void OnStartClimbPrefix(CharacterClimbing __instance) { EnterClimb(ClimbingCharacter.Invoke(__instance)); } public static void OnStartClimb(CharacterClimbing __instance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) ExitClimb(); if (Mine(ClimbingCharacter.Invoke(__instance))) { float num = Effects.Local[Channel.slipForce]; Vector2 playerSlide = __instance.playerSlide; if (Mathf.Abs(num - 1f) > 0.0001f && playerSlide.y < 0f) { __instance.playerSlide = new Vector2(playerSlide.x, playerSlide.y * num); } } } public static bool OnUseStaminaPrefix(Character __instance, ref float usage, ref bool __result) { if (usage <= 0f || !Mine(__instance)) { return true; } bool flag = (Object)(object)_climbCtx == (Object)(object)__instance && _climbDepth > 0; usage *= StatComposites.StaminaCost(Effects.Local, flag); if (flag) { Ability_OverhangRegen.NoteClimbCost(usage); Ability_HoldRefund.NoteClimbCost(usage); } if (usage <= 0f) { __result = true; return false; } return true; } private static bool ExtendedPullSafe(Character helper, Character target, Vector3 dragPoint) { //IL_0000: 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_0007: 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_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) Vector3 val = dragPoint - target.Center; Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; if (target.data.isClimbing) { if (val.y > 0f) { return val.y >= 0.55f * magnitude; } return false; } return target.Center.y < helper.Center.y + 1f; } public static void OnReachPrefix(CharacterGrabbing __instance) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_007a: 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_00cc: 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_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_00f7: 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_0123: Unknown result type (might be due to invalid IL or missing references) Character val = GrabbingCharacter.Invoke(__instance); if (!Mine(val) || !val.data.isReaching || val.data.dead || val.data.passedOut) { return; } Ability_HelpCost ability_HelpCost = LocalCards.Get<Ability_HelpCost>(); if (ability_HelpCost == null) { return; } float num = 4f * Effects.Local[Channel.helpReach]; Vector3 dragPoint = val.Center + Util.ZeroY(val.data.lookDirection * __instance.extendReachDistance); foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)val) && !allCharacter.isBot && !allCharacter.data.dead) { float num2 = Vector3.Distance(val.Center, allCharacter.Center); if (!(num2 > num) && !(Vector3.Angle(val.data.lookDirection, allCharacter.Center - val.Center) > 60f) && CharacterGrabbing.TargetCanBeHelped(allCharacter, val) && (!(num2 > 4f) || ExtendedPullSafe(val, allCharacter, dragPoint))) { ability_HelpCost.OnPull(val); break; } } } } public static void OnTryWallClimbPrefix(CharacterClimbing __instance, ref float raycastDistance) { if (Mine(ClimbingCharacter.Invoke(__instance))) { raycastDistance *= Effects.Local[Channel.grabReach]; } } public static void OnReach(CharacterGrabbing __instance) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) Character val = GrabbingCharacter.Invoke(__instance); Character localCharacter = Character.localCharacter; if ((Object)(object)val == (Object)null || !Mine(localCharacter) || (Object)(object)val == (Object)(object)localCharacter || localCharacter.data.dead) { return; } float num = Effects.ActorChannel(NetSend.ActorOf(val), Channel.helpReach); if (num <= 1.0001f) { return; } float num2 = Vector3.Distance(val.Center, localCharacter.Center); if (num2 <= 4f || num2 > 4f * num || Vector3.Angle(val.data.lookDirection, localCharacter.Center - val.Center) > 60f || !CharacterGrabbing.TargetCanBeHelped(localCharacter, val)) { return; } Vector3 val2 = val.Center + Util.ZeroY(val.data.lookDirection * __instance.extendReachDistance); if ((!((Object)(object)_pullLatchHelper == (Object)(object)val) || !(Time.time <= _pullLatchExpire)) && !ExtendedPullSafe(val, localCharacter, val2)) { return; } _pullLatchHelper = val; _pullLatchExpire = Time.time + 0.25f; if (localCharacter.IsStuck()) { UnStick(localCharacter); } localCharacter.refs.afflictions.SubtractStatus((STATUSTYPE)11, 1f, false, false); localCharacter.refs.afflictions.SubtractStatus((STATUSTYPE)14, 1f, false, false); DragTowards(localCharacter, val2, Mathf.Lerp(70f, 45f, Mathf.InverseLerp(4f, 4f * num, num2))); LimitFalling(localCharacter); localCharacter.data.sinceGrabFriend = 0f; try { GUIManager.instance.Grasp(); } catch { } } public static void OnClimbingSlidePrefix(CharacterClimbing __instance, out float __state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) __state = __instance.playerSlide.y; _slideBefore = __state; _slideTracked = true; } public static void OnClimbingSlide(CharacterClimbing __instance, float __state) { _slideTracked = false; } public static void OnRequestedPositionPrefix(CharacterClimbing __instance, out float __state) { //IL_0069: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) Character val = ClimbingCharacter.Invoke(__instance); __state = (((Object)(object)val != (Object)null && (Object)(object)val.data != (Object)null) ? val.data.slippy : 0f); if (!Mine(val)) { return; } float num = Effects.Local[Channel.slipForce]; if (Mathf.Abs(num - 1f) < 0.0001f) { return; } if (_slideTracked) { Vector2 playerSlide = __instance.playerSlide; if (playerSlide.y < _slideBefore) { __instance.playerSlide = new Vector2(playerSlide.x, _slideBefore + (playerSlide.y - _slideBefore) * num); } _slideTracked = false; } val.data.slippy = __state * num; } public static void OnRequestedPosition(CharacterClimbing __instance, float __state) { Character val = ClimbingCharacter.Invoke(__instance); if (Mine(val)) { val.data.slippy = __state; } } public static void OnJumpGravity(CharacterMovement __instance, ref Vector3 __result) { //IL_005a: 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_0077: Unknown result type (might be due to invalid IL or missing references) if (__result.y >= 0f) { return; } Character val = MovementCharacter.Invoke(__instance); if (Mine(val) && val.data.isJumping && !(val.data.sinceJump > 0.75f)) { float num = Effects.Local[Channel.jumpHeight]; if (!(num <= 1.0001f)) { __result /= 1f + 0.5f * (num - 1f); } } } public static void OnCharacterJumped(Character character, bool doubleJump) { if (doubleJump && Mine(character)) { Ability_SecondSpring.Active?.OnExtraJumpUsed(character); } } public static void OnDynamiteSourcePrefix(out DynamiteSpawnState __state) { __state = null; if (RunState.RunStarted) { __state = new DynamiteSpawnState { PreviousDepth = _dynamiteSpawnDepth, Existing = new HashSet<int>() }; AOE[] array = Object.FindObjectsOfType<AOE>(true); foreach (AOE val in array) { __state.Existing.Add(((Object)val).GetInstanceID()); } _dynamiteSpawnDepth++; } } public static Exception OnDynamiteSourceFinalizer(Exception __exception, DynamiteSpawnState __state) { if (__state == null) { return __exception; } _dynamiteSpawnDepth = __state.PreviousDepth; AOE[] array = Object.FindObjectsOfType<AOE>(true); foreach (AOE val in array) { if (!__state.Existing.Contains(((Object)val).GetInstanceID()) && (Object)(object)((Component)val).GetComponent<DynamiteCardBlast>() == (Object)null) { ((Component)val).gameObject.AddComponent<DynamiteCardBlast>(); } } return __exception; } public static void OnDynamiteFusePrefix(out bool __state) { __state = _dynamiteBlast; _dynamiteBlast = true; } public static Exception OnDynamiteFuseFinalizer(Exception __exception, bool __state) { _dynamiteBlast = __state; return __exception; } public static void OnBlastContextPrefix(AOE __instance, out bool __state) { __state = _dynamiteBlast; _dynamiteBlast = _dynamiteSpawnDepth > 0 || (Object)(object)((Component)__instance).GetComponent<DynamiteCardBlast>() != (Object)null; } public static Exception OnBlastContextFinalizer(Exception __exception, bool __state) { _dynamiteBlast = __state; return __exception; } public static void OnThornInteractTime(ThornOnMe __instance, ref float __result) { ScaleThornTime(__instance, ref __result); } public static void OnThornPopOutTime(ThornOnMe __instance, ref float __result) { ScaleThornTime(__instance, ref __result); } private static void ScaleThornTime(ThornOnMe thorn, ref float time) { if (RunState.RunStarted && !((Object)(object)thorn == (Object)null) && thorn.isThorn && !((Object)(object)thorn.character == (Object)null) && !(time <= 0f)) { time *= Effects.ActorChannel(NetSend.ActorOf(thorn.character), Channel.thornRemovalTime); } } public static void OnPostReviveStatusPrefix(CharacterAfflictions afflictions, out float __state) { __state = -1f; if ((Object)(object)afflictions != (Object)null && Mine(afflictions.character)) { __state = afflictions.GetCurrentStatus((STATUSTYPE)5); } } public static void OnPostReviveStatus(CharacterAfflictions afflictions, float __state) { if (!(__state < 0f) && !((Object)(object)afflictions == (Object)null) && Mine(afflictions.character)) { float multiplier = Effects.ActorChannel(NetSend.ActorOf(afflictions.character), Channel.reviveCurse); float currentStatus = afflictions.GetCurrentStatus((STATUSTYPE)5); float num = ReviewedEffectMath.RevivalCurse(__state, currentStatus, multiplier); if (Mathf.Abs(num - currentStatus) > 1E-05f) { afflictions.SetStatus((STATUSTYPE)5, num, true); } } } public static void OnCarriedDeathPrefix(Character __instance, out float __state) { __state = -1f; if (Mine(__instance) && !__instance.data.dead && __instance.data.fullyPassedOut) { __state = __instance.data.deathTimer; } } public static void OnCarriedDeath(Character __instance, float __state) { if (!(__state < 0f) && Mine(__instance) && !__instance.data.dead && __instance.data.fullyPassedOut) { Character carrier = __instance.data.carrier; if (!((Object)(object)carrier == (Object)null) && !carrier.data.dead) { float multiplier = Effects.ActorChannel(NetSend.ActorOf(carrier), Channel.carriedDeathRate); __instance.data.deathTimer = ReviewedEffectMath.CarriedDeathTimer(__state, __instance.data.deathTimer, multiplier, Time.fixedDeltaTime / 60f); } } } public static void OnPassedOut(Character __instance) { if (Mine(__instance) && !__instance.isBot) { LocalCards.OnDown(__instance); } } public static void OnDiedPrefix(Character __instance, out bool __state) { __state = (Object)(object)__instance.data != (Object)null && (__instance.data.passedOut || __instance.data.fullyPassedOut); if (NetSend.IsHost && EternalReviveLikely(__instance)) { _endGameHoldUntil = Time.time + 8f; _endGameRecheck = __instance; } } public static void OnDied(Character __instance, bool __state) { if (Mine(__instance) && !__instance.isBot) { if (!__state) { LocalCards.OnDown(__instance); } LocalCards.OnDeath(__instance); } } internal static void ResetEndGameHold() { _endGameHoldUntil = 0f; _endGameRecheck = null; } public static bool OnCheckEndGamePrefix(Character __instance) { if (Time.time >= _endGameHoldUntil) { return true; } _endGameRecheck = __instance; return false; } internal static void TickEndGameHold() { if ((Object)(object)_endGameRecheck == (Object)null || Time.time < _endGameHoldUntil) { return; } Character endGameRecheck = _endGameRecheck; _endGameRecheck = null; try { endGameRecheck.CheckEndGame(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("End-game recheck: " + ex.Message)); } } private static bool EternalReviveLikely(Character victim) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)victim == (Object)null || victim.isBot) { return false; } int num = NetSend.ActorOf(victim); CardSettings current = CardSettings.Current; Character val = default(Character); foreach (KeyValuePair<int, List<byte>> item in Effects.CardsByActor) { foreach (byte item2 in item.Value) { CardDef cardDef = current.Card(item2); if (cardDef != null && !(cardDef.Ability != "EternalCampfire") && !Ability_EternalCampfire.Arbiter.UsedInBiome(item.Key, LocalCards.Biome)) { if (item.Key == num) { return true; } if (PlayerHandler.TryGetCharacter(item.Key, ref val) && !((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null) && !val.data.dead && Vector3.Distance(val.Center, victim.Center) <= current.Param(cardDef, "radius", 15f) + 2f) { return true; } } } } } catch { } return false; } public static bool OnFedItemPrefix(Character __instance, int itemPhotonID) { if (!RunState.RunStarted) { return true; } try { PhotonView val = PhotonView.Find(itemPhotonID); Item val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Item>() : null); if (!Mine(__instance) || (!__instance.data.passedOut && !__instance.data.fullyPassedOut)) { return true; } Character val3 = (((Object)(object)val2 != (Object)null) ? val2.trueHolderCharacter : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)__instance) { return true; } _lastFeederActor = NetSend.ActorOf(val3); _lastFedTime = Time.time; } catch { } return true; } public static void OnUnPassedOut(Character __instance) { if (Mine(__instance)) { LocalCards.OnRecovered(); if (_lastFeederActor != int.MinValue && Time.time - _lastFedTime < 20f) { NetSend.RaiseTo(new RevivedBy { victimActor = NetSend.LocalActor }, _lastFeederActor); } _lastFeederActor = int.MinValue; } } public static void OnRespawnChestUsedPrefix(Character interactor) { if (!Mine(interactor)) { return; } bool flag = true; try { flag = Ascents.canReviveDead; } catch { } if (!flag) { return; } foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)interactor) && !allCharacter.isBot && !((Object)(object)allCharacter.data == (Object)null) && (allCharacter.data.dead || allCharacter.data.fullyPassedOut)) { Ability_HerosArrival.OnRevivedTeammate(NetSend.ActorOf(allCharacter)); break; } } } public static bool OnKillPlanePrefix(Collision other) { if (other == null || (Object)(object)other.collider == (Object)null) { return true; } Character val = default(Character); if (!CharacterRagdoll.TryGetCharacterFromCollider(other.collider, ref val) || !Mine(val)) { return true; } Ability_PhoenixClause owned = Ability_PhoenixClause.Owned; if (owned != null) { return !owned.TryPreventKillPlane(val); } return true; } public static void ResetStatusCarries() { AddCarry.Reset(); SubCarry.Reset(); _petrifyCarry = 0f; _injuryCommitted = 0f; _shareOwed.Clear(); } private static bool Mine(Character c) { if ((Object)(object)c != (Object)null && c.IsLocal) { return RunState.RunStarted; } return false; } public static void OnFallDamagePrefix(CharacterMovement __instance) { _fallDepth++; } public static void OnFallDamage(CharacterMovement __instance) { if (_fallDepth > 0) { _fallDepth--; } } public static void OnClimbFallDamagePrefix(CharacterClimbing __instance) { _fallDepth++; } public static void OnClimbFallDamage(CharacterClimbing __instance) { if (_fallDepth > 0) { _fallDepth--; } } public static bool OnAddStatusPrefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount, bool fromRPC, bool ignoreInvincibility, bool ignoreSkeleton, ref bool __result, out bool __state) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected I4, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_00c0: 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) __state = false; if (amount <= 0f) { return true; } Character character = __instance.character; if (!Mine(character)) { return true; } if ((int)statusType == 13) { return true; } bool raw = CardStatus.Raw; float num = amount; if (!raw) { if ((int)statusType == 0 && NativeInjuryRules.Blocks(character.isZombie, character.statusesLocked, character.isScoutmaster, AfflictionsInAirport.Invoke(__instance), NativeInvincible.Invoke(character.data), ignoreInvincibility)) { return true; } bool flag = (int)statusType == 0 && _fallDepth > 0; amount *= Effects.StatusGainMultiplier(statusType, flag); if ((int)statusType == 3 && amount > 0f) { amount *= Ability_GasImmunity.PoisonFactor(num); } if (flag && amount > 0f) { amount *= Ability_BandageBrace.FallFactor(character); } if ((int)statusType == 0 && _dynamiteBlast) { amount *= Effects.Local[Channel.dynamiteInjury]; } if ((int)statusType == 0 && amount > 0f) { amount = ResolveInjury(character, amount, flag, ignoreInvincibility, ignoreSkeleton, out var prevented); if (prevented) { __result = false; return false; } } if (StatComposites.CancelsStatus(amount)) { __result = false; return false; } } int status = (int)statusType; if (raw || Mathf.Abs(amount - num) > 1E-06f || AddCarry.Of(status) > 0f) { amount = CarryAdd(__instance, character, statusType, amount, ignoreInvincibility, ignoreSkeleton); } __state = fromRPC && Mathf.Abs(amount - num) > 1E-05f; return true; } private static float CarryAdd(CharacterAfflictions aff, Character ch, STATUSTYPE t, float amount, bool ignoreInvincibility, bool ignoreSkeleton) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected I4, but got Unknown if (!NativeAccepts(aff, ch, t, ignoreInvincibility)) { return amount; } float num = 1f; if (ch.data.isSkeleton && (int)t == 0 && !ignoreSkeleton) { num *= 8f; } if (NativeDifficultyScaled(t)) { num *= Ascents.etcDamageMultiplier; } if (num <= 0f) { return amount; } float[] array = IncrementalStatuses.Invoke(aff); int num2 = (int)t; if (array == null || num2 >= array.Length) { return amount; } bool resetPending; float num3 = AddCarry.Route(num2, array[num2], amount * num, out resetPending); if (resetPending) { array[num2] = 0f; } return num3 / num; } private static bool NativeAccepts(CharacterAfflictions aff, Character ch, STATUSTYPE t, bool ignoreInvincibility) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0040: 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_0071: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 if (ch.isZombie && (int)t != 6 && (int)t != 11) { return false; } if (ch.statusesLocked || ch.isScoutmaster || AfflictionsInAirport.Invoke(aff)) { return false; } if (ch.data.isSkeleton && (int)t != 0 && (int)t != 5 && (int)t != 14 && (int)t != 11) { return false; } if (!ignoreInvincibility && NativeInvincible.Invoke(ch.data) && (int)t != 5) { return false; } if ((int)t == 1 && !aff.canGetHungry) { return false; } return true; } private static bool NativeDifficultyScaled(STATUSTYPE t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if ((int)t != 0 && (int)t != 5 && (int)t != 3 && (int)t != 10 && (int)t != 2 && (int)t != 8) { return (int)t == 6; } return true; } public static void OnAddStatus(CharacterAfflictions __instance, bool __state) { if (__state) { __instance.PushStatuses((Player)null); } } private static float ResolveInjury(Character ch, float amount, bool fall, bool ignoreInvincibility, bool ignoreSkeleton, out bool prevented) { int owner = Effects.SharedBurdenOwner; float shareFactor = ((owner != int.MinValue && owner != NetSend.LocalActor) ? Effects.SharedBurdenFactor : 1f); CardDef cardDef = Array.Find(CardTable.Cards, (CardDef c) => c.Ability == "SharedBurden"); float absorb = ((cardDef != null) ? CardSettings.Current.Param(cardDef, "absorb", 0.5f) : 0.5f); float cap = ((cardDef != null) ? CardSettings.Current.Param(cardDef, "cap", 0.1f) : 0.1f); if (!CardSettings.Current.DrawbacksEnabled) { absorb = 0f; } Ability_DelayedConsequences delayed = (fall ? Ability_DelayedConsequences.Owned : null); Ability_PhoenixClause phoenix = (fall ? Ability_PhoenixClause.Owned : null); Func<float, bool> preventFall = null; if (phoenix != null) { preventFall = delegate(float injury) { float immediate = injury; float deferred = 0f; if (delayed != null) { delayed.Preview(injury, out immediate, out deferred); } return phoenix.TryPreventFatalFall(ch, immediate, deferred, ignoreSkeleton); }; } Func<float, float> deferFall = ((delayed != null) ? ((Func<float, float>)((float injury) => delayed.Defer(injury, ignoreInvincibility, ignoreSkeleton))) : null); return InjuryResolution.Resolve(amount, shareFactor, absorb, cap, fall, preventFall, deferFall, delegate(float share) { OweShare(owner, share); }, out prevented); } private static void OweShare(int owner, float share) { _shareOwed.TryGetValue(owner, out var value); value += share; if (value < 0.02499f) { _shareOwed[owner] = value; return; } _shareOwed[owner] = 0f; NetSend.RaiseTo(new InjuryShare { amount = value }, owner); } public static void OnSubtractStatusPrefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount, bool decreasedNaturally) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected I4, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Invalid comparison between Unknown and I4 //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Invalid comparison between Unknown and I4 if (amount <= 0f || (int)statusType == 13) { return; } Character character = __instance.character; if (!Mine(character)) { return; } bool raw = CardStatus.Raw; float num = amount; if (!raw) { if (decreasedNaturally) { amount *= Effects.NaturalDecayMultiplier(statusType); } else if ((int)statusType == 2 && _itemActionDepth == 0) { float num2 = Effects.Local[Channel.coldDecay]; if ((Object)(object)_heatEmitter != (Object)null && (Object)(object)_heatEmitter != (Object)(object)character) { num2 *= Effects.Local[Channel.huddleStrength]; } amount *= num2; } else if ((int)statusType == 0 && _itemActionDepth == 0) { amount *= Effects.Local[Channel.healReceived]; } } int num3 = (int)statusType; bool flag = !decreasedNaturally && ((int)statusType == 3 || (int)statusType == 10); if ((!raw && !_itemScaled && Mathf.Abs(amount - num) <= 1E-06f && (flag || SubCarry.Of(num3) <= 0f)) || character.statusesLocked || (character.isZombie && (int)statusType != 6 && (int)statusType != 11)) { return; } if (__instance.GetCurrentStatus(statusType) <= 0f) { SubCarry.Clear(num3); return; } float[] array = DecrementalStatuses.Invoke(__instance); if (array == null || num3 >= array.Length) { return; } if (raw) { SubCarry.Bank(num3, array[num3], amount); return; } amount = SubCarry.Route(num3, array[num3], amount, out var resetPending); if (resetPending) { array[num3] = 0f; } } public static void OnAddPetrifyPrefix(CharacterAfflictions __instance, ref int petrify) { if (petrify > 0 && !CardStatus.Raw && Mine(__instance.character)) { float num = StatComposites.StatusGain(Effects.Local, Channel.petrifyRate); if (!(Mathf.Abs(num - 1f) <= 0.0001f) || !(_petrifyCarry <= 0f)) { petrify = StatusCarry.Whole(ref _petrifyCarry, (float)petrify * num); } } } public static void OnHeatEmissionPrefix(CharacterHeatEmission __instance, out bool __state) { __state = false; Character val = (_heatEmitter = HeatEmissionCharacter.Invoke(__instance)); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null) && !(val.data.sinceAddedCold < 3f)) { __state = HeatEmissionCounter.Invoke(__instance) + Time.deltaTime >= __instance.rate; } } public static void OnHeatEmission(CharacterHeatEmission __instance, bool __state) { //IL_005a: 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) Character heatEmitter = _heatEmitter; _heatEmitter = null; if (!__state || (Object)(object)heatEmitter == (Object)null) { return; } Character localCharacter = Character.localCharacter; if (!Mine(localCharacter) || (Object)(object)heatEmitter == (Object)(object)localCharacter || localCharacter.data.dead) { return; } float num = Effects.Local[Channel.huddleStrength]; if (num <= 1.0001f) { return; } float num2 = Vector3.Distance(((Component)__instance).transform.position, localCharacter.Center); if (num2 < __instance.radius || num2 >= __instance.radius * num) { return; } _heatEmitter = heatEmitter; try { localCharacter.refs.afflictions.SubtractStatus((STATUSTYPE)2, __instance.heatAmount, false, false); } finally { _heatEmitter = null; } } public static void OnRegenContextPrefix(Character __instance) { _regenChar = __instance; } public static void OnRegenContext(Character __instance) { _regenChar = null; } public static void OnAddStaminaPrefix(Character __instance, ref float add) { if (!(add <= 0f) && !((Object)(object)_regenChar != (Object)(object)__instance) && Mine(__instance)) { add *= Effects.Local[Channel.regenRate]; } } public static void OnCanRegenStamina(Character __instance, ref bool __result) { if (!Mine(__instance)) { return; } float num = Effects.Local[Channel.regenDelay]; if (Mathf.Abs(num) < 0.001f) { return; } CharacterData data = __instance.data; if ((Object)(object)data.currentClimbHandle != (Object)null) { return; } bool flag = data.sinceGrounded > 0.2f && !__instance.refs.afflictions.isWebbed; float num2 = Mathf.Max(0f, ((data.currentStamina > 0f) ? 1f : 2f) + num); if (!__result) { if (!flag && data.sinceUseStamina >= num2) { __result = true; } } else if (num > 0f && !__instance.IsStuck() && data.sinceUseStamina < num2) { __result = false; } } public static void OnGetMaxStamina(Character __instance, ref float __result) { if (Mine(__instance)) { float num = Effects.Local[Channel.maxStamina]; if (!(Mathf.Abs(num) < 0.0001f)) { __result = Mathf.Max(Mathf.Min(1f + num, 1.9f) - __instance.refs.afflictions.statusSum, 0f); } } } internal static float PassOutThreshold() { return Mathf.Min(1f + Mathf.Max(0f, Effects.Local[Channel.maxStamina]), 1.9f); } public static void OnShouldPassOut(CharacterAfflictions __instance, ref bool __result) { if (__result && !((Object)(object)__instance.character == (Object)null) && Mine(__instance.character)) { __result = __instance.statusSum > PassOutThreshold() - 0.01f; } } internal static void SampleInjuryCapFloor(Character local) { _injuryCommitted = (((Object)(object)local != (Object)null && local.refs != null && (Object)(object)local.refs.afflictions != (Object)null) ? local.refs.afflictions.GetCurrentStatus((STATUSTYPE)0) : 0f); } public static void OnGetStatusCap(CharacterAfflictions __instance, STATUSTYPE type, ref float __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)type == 0 && !((Object)(object)__instance.character == (Object)null) && RunState.RunStarted) { __result = Mathf.Max(__result, Mine(__instance.character) ? Mathf.Max(PassOutThreshold(), _injuryCommitted) : 1.9f); } } public static bool OnScorpionAttackPrefix(Scorpion __instance, Character character) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || !character.IsLocal || !Mine(character)) { return true; } float num = PassOutThreshold(); if (num <= 1.