Decompiled source of Made In AbyssCurse For TFA v1.2.1

MadeInAPeak.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MadeInAPeak")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MadeInAPeak")]
[assembly: AssemblyTitle("MadeInAPeak")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MadeInAPeak
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MadeInAPeak";

		public const string PLUGIN_NAME = "MadeInAPeak";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace MadeInPeak
{
	[BepInPlugin("RR.MadeInPeak", "MadeInAPeak Mod", "2.1.0.0")]
	public class AbyssCurseModBase : BaseUnityPlugin
	{
		public const string ModGUID = "RR.MadeInPeak";

		public const string ModName = "MadeInAPeak Mod";

		public const string ModVersion = "2.1.0.0";

		public const string NetworkPropertyKey = "MIP_VER";

		private readonly Harmony harmony = new Harmony("RR.MadeInPeak");

		public static AbyssCurseModBase Instance = null;

		public static ManualLogSource mls = null;

		public static float localMaxHeight = float.MinValue;

		public static float ledgeAnchorY = float.MinValue;

		public static float ledgeRestTimer = 0f;

		public static float reviveGraceTimer = 0f;

		public static bool nadirSoulFreed = false;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = ((BaseUnityPlugin)this).Logger;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			((Component)this).gameObject.AddComponent<LobbySecurityHandler>();
			CharacterHeightPatch.InitReflection();
			harmony.PatchAll();
			mls.LogInfo((object)"MadeInAPeak v2.1.0.0 loaded successfully.");
		}
	}
	public static class CurseSettings
	{
		public const float HeightDropTriggerDistance = 10f;

		public const float MinimumAltitudeForCurse = 4f;

		public const float LedgeVerticalBand = 1.5f;

		public const float AcclimatizeDuration = 15f;

		public const float ShoreCrabAmount = 0.15f;

		public const float ShoreCrabDecayDuration = 5f;

		public const float TropicsPoison = 0.05f;

		public const float TropicsStumbleDuration = 0.05f;

		public const float RootsSpores = 0.08f;

		public const float RootsNumbDuration = 10f;

		public const float AlpineCold = 0.13f;

		public const float AlpineDrowsy = 0.05f;

		public const float AlpineBlindDuration = 4f;

		public const float MesaHotDay = 0.15f;

		public const int MesaPhysicalThorns = 2;

		public const float CalderaHot = 0.05f;

		public const float CalderaHunger = 0.03f;

		public const float KilnInjury = 0.1f;

		public const float KilnCurse = 0.03f;

		public const float KilnHot = 0.2f;

		public const float KilnPetrify = 0.05f;

		public const float KilnWeb = 0.3f;

		public const float GloomDrowsy = 0.08f;

		public const float GloomNumbDuration = 4f;

		public const float GloomCurse = 0f;

		public const float CitadelInjury = 0.1f;

		public const float CitadelCurse = 0.03f;

		public const float CitadelPetrify = 0.075f;

		public const float CitadelNumbDuration = 10f;

		public const float CitadelStumbleDuration = 1f;

		public const float CitadelCrabAmount = 0.5f;

		public const float CitadelCrabDecayDuration = 5f;

		public const float VoidInjury = 0.15f;

		public const float VoidCurse = 0.1f;

		public const float VoidBlindDuration = 5f;

		public const float VoidCollapseDuration = 1.5f;
	}
	public class LobbySecurityHandler : MonoBehaviourPunCallbacks, IOnEventCallback
	{
		public const byte SpawnDynamiteEventCode = 188;

		private static readonly HashSet<int> verifiedActors = new HashSet<int>();

		public override void OnEnable()
		{
			((MonoBehaviourPunCallbacks)this).OnEnable();
			PhotonNetwork.AddCallbackTarget((object)this);
			PhotonNetwork.EnableCloseConnection = true;
		}

		public override void OnDisable()
		{
			((MonoBehaviourPunCallbacks)this).OnDisable();
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		public override void OnJoinedRoom()
		{
			//IL_0034: 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_0049: Expected O, but got Unknown
			//IL_004b: Expected O, but got Unknown
			verifiedActors.Clear();
			AbyssCurseModBase.nadirSoulFreed = false;
			if (PhotonNetwork.LocalPlayer != null)
			{
				verifiedActors.Add(PhotonNetwork.LocalPlayer.ActorNumber);
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"MIP_VER", (object)"2.1.0.0");
				Hashtable val2 = val;
				PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val3 in playerList)
			{
				if (!val3.IsLocal)
				{
					((MonoBehaviour)this).StartCoroutine(VerifyPlayerTimeout(val3));
				}
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			if (PhotonNetwork.IsMasterClient && newPlayer != null && !newPlayer.IsLocal)
			{
				((MonoBehaviour)this).StartCoroutine(VerifyPlayerTimeout(newPlayer));
			}
		}

		public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
			if (targetPlayer != null && changedProps != null && ((Dictionary<object, object>)(object)changedProps).TryGetValue((object)"MIP_VER", out object value) && value as string == "2.1.0.0")
			{
				verifiedActors.Add(targetPlayer.ActorNumber);
				AbyssCurseModBase.mls.LogInfo((object)("Verified " + targetPlayer.NickName + " has MadeInPeak."));
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (photonEvent.Code == 188 && PhotonNetwork.IsMasterClient)
			{
				object[] array = (object[])photonEvent.CustomData;
				Vector3 spawnPos = default(Vector3);
				((Vector3)(ref spawnPos))..ctor((float)array[0], (float)array[1], (float)array[2]);
				CharacterHeightPatch.DynamiteNetworkHelper.SpawnRoomDynamite(spawnPos);
			}
		}

		private IEnumerator VerifyPlayerTimeout(Player player)
		{
			float timeout = 3.5f;
			while (timeout > 0f)
			{
				if (player == null || Array.IndexOf(PhotonNetwork.PlayerList, player) < 0 || verifiedActors.Contains(player.ActorNumber))
				{
					yield break;
				}
				if (player.CustomProperties != null && ((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"MIP_VER", out object verObj) && verObj as string == "2.1.0.0")
				{
					verifiedActors.Add(player.ActorNumber);
					yield break;
				}
				timeout -= 0.5f;
				yield return (object)new WaitForSecondsRealtime(0.5f);
				verObj = null;
			}
			AbyssCurseModBase.mls.LogWarning((object)("[Security] Kicking " + player.NickName + ": Missing MadeInPeak mod."));
		}
	}
	[HarmonyPatch(typeof(GlobalEvents), "TriggerSoulFreed")]
	public static class NadirSoulFreedPatch
	{
		[HarmonyPostfix]
		public static void Postfix(int phase)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (phase == 0)
			{
				AbyssCurseModBase.nadirSoulFreed = true;
				ManualLogSource mls = AbyssCurseModBase.mls;
				if (mls != null)
				{
					mls.LogInfo((object)"[MadeInAPeak] Soul freed in Nadir! Void curse is now ACTIVE.");
				}
				if ((Object)(object)Character.localCharacter != (Object)null)
				{
					AbyssCurseModBase.localMaxHeight = Character.localCharacter.Center.y;
					AbyssCurseModBase.ledgeAnchorY = Character.localCharacter.Center.y;
					AbyssCurseModBase.ledgeRestTimer = 0f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MapHandler), "InitializeMap")]
	public static class MapInitResetPatch
	{
		[HarmonyPostfix]
		public static void Postfix()
		{
			AbyssCurseModBase.nadirSoulFreed = false;
		}
	}
	[HarmonyPatch(typeof(Character), "Update")]
	internal class CharacterHeightPatch
	{
		public static class DynamiteNetworkHelper
		{
			public static void RequestSpawnDynamite(Vector3 spawnPos)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				//IL_0066: 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)
				if (PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom)
				{
					SpawnRoomDynamite(spawnPos);
					return;
				}
				object[] array = new object[3] { spawnPos.x, spawnPos.y, spawnPos.z };
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				};
				PhotonNetwork.RaiseEvent((byte)188, (object)array, val, SendOptions.SendReliable);
			}

			public static void SpawnRoomDynamite(Vector3 spawnPos)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					GameObject val = PhotonNetwork.InstantiateRoomObject("0_Items/Dynamite", spawnPos, Random.rotation, (byte)0, (object[])null);
					if (!((Object)(object)val == (Object)null))
					{
						PhotonView component = val.GetComponent<PhotonView>();
						if ((Object)(object)component != (Object)null)
						{
							component.RPC("SetKinematicRPC", (RpcTarget)0, new object[3]
							{
								false,
								val.transform.position,
								val.transform.rotation
							});
						}
						Rigidbody component2 = val.GetComponent<Rigidbody>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.isKinematic = false;
							component2.useGravity = true;
							Vector3 linearVelocity = default(Vector3);
							((Vector3)(ref linearVelocity))..ctor(Random.Range(-1.5f, 1.5f), -2f, Random.Range(-1.5f, 1.5f));
							component2.linearVelocity = linearVelocity;
							component2.angularVelocity = Random.insideUnitSphere * 8f;
						}
						Dynamite component3 = val.GetComponent<Dynamite>();
						if ((Object)(object)component3 != (Object)null)
						{
							component3.LightFlare();
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource mls = AbyssCurseModBase.mls;
					if (mls != null)
					{
						mls.LogError((object)("Failed to spawn room dynamite: " + ex.Message));
					}
				}
			}
		}

		private static bool reflectionInitialized = false;

		private static PropertyInfo? tfaActiveProp;

		private static FieldInfo? tfaVoidActiveField;

		private static PropertyInfo? tfaCurrentStageProp;

		private static FieldInfo? tfaSegIndexField;

		private static FieldInfo? tfaChainIndexField;

		private static FieldInfo? tfaTitleField;

		private static AmbienceAudio? cachedAmbience;

		private static readonly Dictionary<string, FieldInfo?> stingerFieldCache = new Dictionary<string, FieldInfo>();

		private static void ApplyTemporarySkeleton(Character character, float duration)
		{
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.data == (Object)null) && (Object)(object)AbyssCurseModBase.Instance != (Object)null)
			{
				((MonoBehaviour)AbyssCurseModBase.Instance).StartCoroutine(TemporarySkeletonRoutine(character, duration));
			}
		}

		private static IEnumerator TemporarySkeletonRoutine(Character character, float duration)
		{
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.data == (Object)null) && !((Object)(object)character.refs?.afflictions == (Object)null) && !character.data.isSkeleton)
			{
				float originalCurse = character.refs.afflictions.GetCurrentStatus((STATUSTYPE)5);
				character.data.SetSkeleton(true);
				character.refs.afflictions.SetStatus((STATUSTYPE)5, originalCurse, true);
				yield return (object)new WaitForSeconds(duration);
				if ((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null && !character.data.dead)
				{
					float curseBeforeRevert = character.refs.afflictions.GetCurrentStatus((STATUSTYPE)5);
					character.data.SetSkeleton(false);
					character.refs.afflictions.SetStatus((STATUSTYPE)5, curseBeforeRevert, true);
				}
			}
		}

		internal static void InitReflection()
		{
			if (reflectionInitialized)
			{
				return;
			}
			reflectionInitialized = true;
			try
			{
				Type type = AccessTools.TypeByName("TrueFinalAscent.FinalAscent");
				if (type != null)
				{
					tfaActiveProp = AccessTools.Property(type, "Active");
				}
				Type type2 = AccessTools.TypeByName("VoidBiome");
				if (type2 != null)
				{
					tfaVoidActiveField = AccessTools.Field(type2, "VoidBiomeActive");
				}
				Type type3 = AccessTools.TypeByName("TrueFinalAscent.FinalAscentSegments");
				if (type3 != null)
				{
					tfaCurrentStageProp = AccessTools.Property(type3, "CurrentStage");
				}
				Type type4 = AccessTools.TypeByName("TrueFinalAscent.FinalAscentStage");
				if (type4 != null)
				{
					tfaSegIndexField = AccessTools.Field(type4, "SegmentIndex");
					tfaChainIndexField = AccessTools.Field(type4, "ChainIndex");
					tfaTitleField = AccessTools.Field(type4, "Title");
				}
			}
			catch
			{
			}
		}

		private static void DropHeldItem(Character character)
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null)
			{
				return;
			}
			CharacterData data = character.data;
			if (!((Object)(object)((data != null) ? data.currentItem : null) == (Object)null) && !((Object)(object)character.refs?.items == (Object)null) && character.refs.items.currentSelectedSlot.IsSome)
			{
				Item currentItem = character.data.currentItem;
				byte value = character.refs.items.currentSelectedSlot.Value;
				Player player = character.player;
				ItemSlot val = ((player != null) ? player.GetItemSlot(value) : null);
				if (val != null && (!((Object)(object)val.prefab != (Object)null) || val.prefab.UIData.canDrop))
				{
					((MonoBehaviourPun)character.refs.items).photonView.RPC("DropItemRpc", (RpcTarget)0, new object[7]
					{
						0f,
						value,
						currentItem.transform.position,
						Vector3.down * 2f,
						currentItem.transform.rotation,
						val.data,
						false
					});
					character.refs.items.EquipSlot(Optionable<byte>.None);
				}
			}
		}

		[HarmonyPostfix]
		private static void heightPatch(Character __instance)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || !__instance.IsLocal || __instance.isBot || (Object)(object)__instance.player == (Object)null || (Object)(object)__instance.refs?.afflictions == (Object)null)
			{
				return;
			}
			float y = __instance.Center.y;
			if (__instance.IsGhost || __instance.data.dead)
			{
				AbyssCurseModBase.localMaxHeight = y;
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
				AbyssCurseModBase.reviveGraceTimer = 3f;
				return;
			}
			if (AbyssCurseModBase.reviveGraceTimer > 0f)
			{
				AbyssCurseModBase.reviveGraceTimer -= Time.deltaTime;
				AbyssCurseModBase.localMaxHeight = y;
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
				return;
			}
			if (AbyssCurseModBase.localMaxHeight == float.MinValue)
			{
				AbyssCurseModBase.localMaxHeight = y;
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
			}
			if (y > AbyssCurseModBase.localMaxHeight)
			{
				AbyssCurseModBase.localMaxHeight = y;
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
				return;
			}
			if (y <= 4f)
			{
				AbyssCurseModBase.localMaxHeight = y;
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
				return;
			}
			if (Mathf.Abs(y - AbyssCurseModBase.ledgeAnchorY) <= 1.5f)
			{
				AbyssCurseModBase.ledgeRestTimer += Time.deltaTime;
				if (AbyssCurseModBase.localMaxHeight > y)
				{
					float num = 2f / 3f * Time.deltaTime;
					AbyssCurseModBase.localMaxHeight = Mathf.MoveTowards(AbyssCurseModBase.localMaxHeight, y, num);
				}
			}
			else
			{
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
			}
			if (!(AbyssCurseModBase.localMaxHeight - y < 10f))
			{
				AbyssCurseModBase.localMaxHeight = y;
				AbyssCurseModBase.ledgeAnchorY = y;
				AbyssCurseModBase.ledgeRestTimer = 0f;
				string area = DetectCurrentArea();
				if (IsInClimbingSection(area))
				{
					ApplyCurseLocal(__instance, area);
				}
			}
		}

		private static void ApplyCurseLocal(Character character, string area)
		{
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			switch (area)
			{
			case "Shore":
				ApplyCrabWithDecay(character, 0.15f, 5f);
				break;
			case "Tropics":
				AddStatusLocal(character, (STATUSTYPE)3, 0.05f);
				TriggerFall(character, 0.05f);
				break;
			case "Roots":
				AddStatusLocal(character, (STATUSTYPE)10, 0.08f);
				ApplyNumbnessLocal(character, 10f);
				break;
			case "Alpine":
				AddStatusLocal(character, (STATUSTYPE)2, 0.13f);
				AddStatusLocal(character, (STATUSTYPE)6, 0.05f);
				ApplyBlindnessLocal(character, 4f);
				break;
			case "Mesa":
			{
				if ((Object)(object)DayNightManager.instance == (Object)null || DayNightManager.instance.isDay >= 0.5f)
				{
					AddStatusLocal(character, (STATUSTYPE)8, 0.15f);
				}
				if (!character.data.isSkeleton)
				{
					character.refs.afflictions.AddThorns(0, 2);
				}
				Vector3 spawnPos = default(Vector3);
				((Vector3)(ref spawnPos))..ctor(character.Center.x, character.Center.y - 0.8f, character.Center.z);
				DynamiteNetworkHelper.RequestSpawnDynamite(spawnPos);
				break;
			}
			case "Caldera":
				AddStatusLocal(character, (STATUSTYPE)8, 0.05f);
				AddStatusLocal(character, (STATUSTYPE)1, 0.03f);
				break;
			case "TheKiln":
				AddStatusLocal(character, (STATUSTYPE)0, 0.1f);
				AddStatusLocal(character, (STATUSTYPE)5, 0.03f);
				AddStatusLocal(character, (STATUSTYPE)8, 0.2f);
				AddStatusLocal(character, (STATUSTYPE)13, 0.05f);
				AddStatusLocal(character, (STATUSTYPE)11, 0.3f);
				break;
			case "Gloom":
				AddStatusLocal(character, (STATUSTYPE)6, 0.08f);
				AddStatusLocal(character, (STATUSTYPE)5, 0f);
				ApplyNumbnessLocal(character, 4f);
				break;
			case "TheCitadel":
				AddStatusLocal(character, (STATUSTYPE)0, 0.1f);
				AddStatusLocal(character, (STATUSTYPE)5, 0.03f);
				AddStatusLocal(character, (STATUSTYPE)13, 0.075f);
				ApplyNumbnessLocal(character, 10f);
				TriggerFall(character, 1f);
				ApplyCrabWithDecay(character, 0.5f, 5f);
				DropHeldItem(character);
				break;
			case "Void":
				if (AbyssCurseModBase.nadirSoulFreed)
				{
					AddStatusLocal(character, (STATUSTYPE)5, 0.1f);
					AddStatusLocal(character, (STATUSTYPE)0, 0.15f);
					ApplyBlindnessLocal(character, 5f);
					TriggerFall(character, 1.5f);
					ApplyTemporarySkeleton(character, 12f);
					DropHeldItem(character);
				}
				break;
			default:
				AbyssCurseModBase.localMaxHeight = -1f;
				break;
			}
		}

		private static void AddStatusLocal(Character character, STATUSTYPE type, float amount)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (!(amount <= 0f) && !((Object)(object)character == (Object)null) && !((Object)(object)character.refs?.afflictions == (Object)null))
			{
				character.refs.afflictions.AddStatus(type, amount, false, true, true, false);
			}
		}

		private static void ApplyNumbnessLocal(Character character, float duration)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (duration <= 0f || (Object)(object)character == (Object)null || (Object)(object)character.refs?.afflictions == (Object)null)
			{
				return;
			}
			try
			{
				character.refs.afflictions.AddAffliction((Affliction)new Affliction_Numb
				{
					totalTime = duration
				}, false);
			}
			catch (Exception ex)
			{
				AbyssCurseModBase.mls.LogError((object)("Failed Numbness: " + ex.Message));
			}
		}

		private static void ApplyBlindnessLocal(Character character, float duration)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (duration <= 0f || (Object)(object)character == (Object)null || (Object)(object)character.refs?.afflictions == (Object)null)
			{
				return;
			}
			try
			{
				character.refs.afflictions.AddAffliction((Affliction)new Affliction_Blind
				{
					totalTime = duration
				}, false);
			}
			catch (Exception ex)
			{
				AbyssCurseModBase.mls.LogError((object)("Failed Blindness: " + ex.Message));
			}
		}

		private static void TriggerFall(Character character, float seconds)
		{
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.refs?.view == (Object)null))
			{
				character.refs.view.RPC("RPCA_Fall", (RpcTarget)0, new object[2] { seconds, 0f });
			}
		}

		private static void ApplyCrabWithDecay(Character character, float amount, float duration)
		{
			AddStatusLocal(character, (STATUSTYPE)4, amount);
			if ((Object)(object)AbyssCurseModBase.Instance != (Object)null)
			{
				((MonoBehaviour)AbyssCurseModBase.Instance).StartCoroutine(CrabDecayRoutine(character, amount, duration));
			}
		}

		private static IEnumerator CrabDecayRoutine(Character character, float amount, float duration)
		{
			yield return (object)new WaitForSeconds(duration);
			if ((Object)(object)character != (Object)null && (Object)(object)character.refs?.afflictions != (Object)null)
			{
				character.refs.afflictions.SubtractStatus((STATUSTYPE)4, amount, false, false);
			}
		}

		private static bool IsInClimbingSection(string area)
		{
			switch (area)
			{
			case "Peak":
				return false;
			case "Shore":
				return true;
			case "Void":
				return AbyssCurseModBase.nadirSoulFreed;
			default:
				if (!(area == "TheCitadel"))
				{
					if ((Object)(object)cachedAmbience == (Object)null)
					{
						cachedAmbience = Object.FindFirstObjectByType<AmbienceAudio>();
					}
					if ((Object)(object)cachedAmbience == (Object)null)
					{
						return true;
					}
					switch (area)
					{
					case "Tropics":
					case "Roots":
						return ReadStingerFlag("playedTropicsOrRoots");
					case "Alpine":
					case "Mesa":
						return ReadStingerFlag("playedAlpineOrMesa");
					case "Caldera":
					case "Gloom":
						return ReadStingerFlag("playedCalderaOrGloom");
					default:
						return true;
					}
				}
				goto case "TheKiln";
			case "TheKiln":
				return true;
			}
		}

		private static bool ReadStingerFlag(string fieldName)
		{
			if (!stingerFieldCache.TryGetValue(fieldName, out FieldInfo value))
			{
				value = AccessTools.Field(typeof(AmbienceAudio), fieldName);
				stingerFieldCache[fieldName] = value;
			}
			if (value != null && (Object)(object)cachedAmbience != (Object)null && value.GetValue(cachedAmbience) is bool result)
			{
				return result;
			}
			return true;
		}

		private static string DetectCurrentArea()
		{
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)Singleton<MountainProgressHandler>.Instance != (Object)null && (Object)(object)Character.localCharacter != (Object)null && Singleton<MountainProgressHandler>.Instance.IsAtPeak(Character.localCharacter.Center))
				{
					return "Peak";
				}
			}
			catch
			{
			}
			try
			{
				if (tfaActiveProp != null && (bool)(tfaActiveProp.GetValue(null) ?? ((object)false)))
				{
					if (tfaVoidActiveField != null && (bool)(tfaVoidActiveField.GetValue(null) ?? ((object)false)))
					{
						return "Void";
					}
					if (tfaCurrentStageProp != null)
					{
						object value = tfaCurrentStageProp.GetValue(null);
						if (value != null)
						{
							int num = ((tfaSegIndexField != null) ? ((int)(tfaSegIndexField.GetValue(value) ?? ((object)0))) : 0);
							int num2 = ((tfaChainIndexField != null) ? ((int)(tfaChainIndexField.GetValue(value) ?? ((object)0))) : 0);
							string text = ((tfaTitleField != null) ? ((tfaTitleField.GetValue(value) as string) ?? "") : "");
							switch (num)
							{
							case 0:
								return "Shore";
							case 1:
								return (num2 == 0) ? "Tropics" : "Roots";
							case 2:
								return (num2 == 0) ? "Alpine" : "Mesa";
							case 3:
								return "Caldera";
							case 4:
								if (num2 == 0)
								{
									return "TheKiln";
								}
								if (num2 == 1)
								{
									return "Gloom";
								}
								if (num2 >= 2)
								{
									return "TheCitadel";
								}
								break;
							}
							if (text.Contains("SHORE"))
							{
								return "Shore";
							}
							if (text.Contains("TROPICS"))
							{
								return "Tropics";
							}
							if (text.Contains("ROOTS"))
							{
								return "Roots";
							}
							if (text.Contains("ALPINE"))
							{
								return "Alpine";
							}
							if (text.Contains("MESA"))
							{
								return "Mesa";
							}
							if (text.Contains("CALDERA"))
							{
								return "Caldera";
							}
							if (text.Contains("KILN"))
							{
								return "TheKiln";
							}
							if (text.Contains("GLOOM"))
							{
								return "Gloom";
							}
							if (text.Contains("CITADEL"))
							{
								return "TheCitadel";
							}
						}
					}
				}
			}
			catch
			{
			}
			MapHandler instance = Singleton<MapHandler>.Instance;
			string text2 = ((instance != null) ? ((object)instance.GetCurrentSegment()/*cast due to .constrained prefix*/).ToString() : null) ?? "";
			MapHandler instance2 = Singleton<MapHandler>.Instance;
			string text3 = ((instance2 != null) ? ((object)instance2.GetCurrentBiome()/*cast due to .constrained prefix*/).ToString() : null) ?? "";
			if (text3.Equals("Shore", StringComparison.OrdinalIgnoreCase) || text2.Equals("Beach", StringComparison.OrdinalIgnoreCase))
			{
				return "Shore";
			}
			if (text3.Equals("Roots", StringComparison.OrdinalIgnoreCase))
			{
				return "Roots";
			}
			if (text3.Equals("Tropics", StringComparison.OrdinalIgnoreCase) || text2.Equals("Tropics", StringComparison.OrdinalIgnoreCase))
			{
				return "Tropics";
			}
			if (text3.Equals("Mesa", StringComparison.OrdinalIgnoreCase))
			{
				return "Mesa";
			}
			if (text3.Equals("Alpine", StringComparison.OrdinalIgnoreCase) || text2.Equals("Alpine", StringComparison.OrdinalIgnoreCase))
			{
				return "Alpine";
			}
			if (text3.Equals("Volcano", StringComparison.OrdinalIgnoreCase) || text2.Equals("Caldera", StringComparison.OrdinalIgnoreCase))
			{
				return "Caldera";
			}
			if (text3.Equals("Swamp", StringComparison.OrdinalIgnoreCase))
			{
				return "Gloom";
			}
			if (text2.Equals("TheKiln", StringComparison.OrdinalIgnoreCase))
			{
				return "TheKiln";
			}
			if (text2.Equals("Void", StringComparison.OrdinalIgnoreCase) || text3.Equals("Void", StringComparison.OrdinalIgnoreCase))
			{
				return "Void";
			}
			return text2;
		}
	}
}