Decompiled source of Rogue Climb v0.10.7

plugins/PeakRoguelike/PeakRoguelike.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Peak.Afflictions;
using Peak.Network;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.UI;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PeakRoguelike")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.10.7.0")]
[assembly: AssemblyInformationalVersion("0.10.7")]
[assembly: AssemblyProduct("PeakRoguelike")]
[assembly: AssemblyTitle("PEAK Roguelike")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.10.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PeakRoguelike
{
	internal class Ambiance : MonoBehaviour
	{
		private const string MenuScene = "Title";

		private const string AirportScene = "Airport";

		internal static readonly Color SkyTop = new Color(0.3f, 0.02f, 0.03f);

		internal static readonly Color SkyMid = new Color(0.72f, 0.08f, 0.05f);

		internal static readonly Color SkyBottom = new Color(0.95f, 0.22f, 0.09f);

		private Image? tint;

		private Image? vignette;

		private Graphic? logo;

		private Image? glow;

		private Color logoColor;

		private bool logoTried;

		private float alpha;

		private float glowAlpha;

		private float nextPoll;

		private float flicker = 1f;

		private float nextFlicker;

		private Vector3? menuMoonDir;

		internal static bool InAirport { get; private set; }

		internal static bool InMenu { get; private set; }

		internal static float SkyStrength => Mathf.Clamp01(InAirport ? ModConfig.AirportSky.Value : (InMenu ? ModConfig.MenuSky.Value : 0f));

		internal static float LightStrength => Mathf.Clamp01(InAirport ? ModConfig.AirportLight.Value : (InMenu ? ModConfig.MenuLight.Value : 0f));

		internal static void Install()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("PEAK Roguelike - Ambiance");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)61;
			Ambiance ambiance = val.AddComponent<Ambiance>();
			SceneManager.sceneLoaded += ambiance.OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)mode == 0)
			{
				InAirport = ((Scene)(ref scene)).name == "Airport";
				InMenu = ((Scene)(ref scene)).name == "Title";
				menuMoonDir = null;
				if (InAirport || InMenu)
				{
					((MonoBehaviour)this).Invoke("RedSkybox", 1f);
				}
			}
		}

		private void Update()
		{
			//IL_001e: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time >= nextPoll)
			{
				nextPoll = Time.time + 0.5f;
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				InAirport = name == "Airport";
				InMenu = name == "Title";
				if (!InMenu)
				{
					logo = null;
					glow = null;
					logoTried = false;
				}
				if (InMenu && !logoTried)
				{
					TryBuildGlow();
				}
			}
			alpha = Mathf.MoveTowards(alpha, InMenu ? ModConfig.MenuFilter.Value : 0f, Time.deltaTime / 1.5f);
			EnsureOverlay();
			bool flag = alpha > 0.001f;
			Image? obj = tint;
			bool enabled = (((Behaviour)vignette).enabled = flag);
			((Behaviour)obj).enabled = enabled;
			((Graphic)tint).color = new Color(0.62f, 0.02f, 0.01f, alpha);
			((Graphic)vignette).color = new Color(0.45f, 0f, 0f, Mathf.Clamp01(alpha * 3.5f));
			if ((Object)(object)logo != (Object)null)
			{
				AnimateLogo();
			}
		}

		private void LateUpdate()
		{
			//IL_0021: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			float skyStrength = SkyStrength;
			if (skyStrength <= 0f || (Object)(object)DayNightManager.instance != (Object)null)
			{
				return;
			}
			Shader.SetGlobalColor("SkyTopColor", SkyTop);
			Shader.SetGlobalColor("SkyMidColor", SkyMid);
			Shader.SetGlobalColor("SkyBottomColor", SkyBottom);
			Camera val = Meteors.Eye();
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 valueOrDefault = menuMoonDir.GetValueOrDefault();
				if (!menuMoonDir.HasValue)
				{
					Vector3 val2 = Quaternion.AngleAxis(-24f, Vector3.up) * Quaternion.AngleAxis(-14f, ((Component)val).transform.right) * ((Component)val).transform.forward;
					valueOrDefault = ((Vector3)(ref val2)).normalized;
					menuMoonDir = valueOrDefault;
				}
				BloodMoon.Visuals.ShowDisc(menuMoonDir.Value, skyStrength);
			}
		}

		private void EnsureOverlay()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			if (!((Object)(object)tint != (Object)null))
			{
				GameObject val = new GameObject("PEAK Roguelike - Ambiance Filter");
				Object.DontDestroyOnLoad((Object)(object)val);
				Canvas val2 = val.AddComponent<Canvas>();
				val2.renderMode = (RenderMode)0;
				val2.sortingOrder = -60;
				tint = Full(val.transform, "Tint", null);
				vignette = Full(val.transform, "Vignette", Vignette());
			}
		}

		private static Image Full(Transform parent, string name, Sprite? sprite)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0034: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			Vector2 offsetMin = (val2.offsetMax = Vector2.zero);
			val2.offsetMin = offsetMin;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			((Graphic)val3).raycastTarget = false;
			((Behaviour)val3).enabled = false;
			return val3;
		}

		private static Sprite Vignette()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = ((float)j + 0.5f) / 128f * 2f - 1f;
					float num2 = ((float)i + 0.5f) / 128f * 2f - 1f;
					float num3 = Mathf.Sqrt(num * num + num2 * num2) / 1.414f;
					val.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.45f, 1f, num3))));
				}
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f));
		}

		private void RedSkybox()
		{
			//IL_015a: 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)
			//IL_017c: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			float skyStrength = SkyStrength;
			Material sky = RenderSettings.skybox;
			string text = (InMenu ? "Menu" : "Airport");
			if ((Object)(object)sky == (Object)null || (Object)(object)sky.shader == (Object)null)
			{
				Plugin.Log.LogInfo((object)(text + " sky: day/night manager " + (((Object)(object)DayNightManager.instance != (Object)null) ? "found" : "none") + ", no skybox."));
				return;
			}
			List<string> list = (from i in Enumerable.Range(0, sky.shader.GetPropertyCount())
				where (int)sky.shader.GetPropertyType(i) == 0
				select sky.shader.GetPropertyName(i)).ToList();
			Plugin.Log.LogInfo((object)(text + " sky: day/night manager " + (((Object)(object)DayNightManager.instance != (Object)null) ? "found" : "none") + ", skybox '" + ((Object)sky).name + "' (" + ((Object)sky.shader).name + "), colours: " + string.Join(", ", list)));
			if (skyStrength <= 0f || list.Count == 0)
			{
				return;
			}
			Material val = new Material(sky)
			{
				name = ((Object)sky).name + " (blood moon)"
			};
			Color val2 = default(Color);
			foreach (string item in list)
			{
				Color color = val.GetColor(item);
				float num = Mathf.Max(((Color)(ref color)).maxColorComponent, 0.05f);
				((Color)(ref val2))..ctor(num, num * 0.12f, num * 0.08f, color.a);
				val.SetColor(item, Color.Lerp(color, val2, skyStrength));
			}
			RenderSettings.skybox = val;
		}

		private void TryBuildGlow()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			List<Graphic> list = (from g in ((Scene)(ref activeScene)).GetRootGameObjects().SelectMany((GameObject r) => r.GetComponentsInChildren<Graphic>(false))
				where ((Behaviour)g).isActiveAndEnabled && (Object)(object)g.canvas != (Object)null
				select g).ToList();
			if (list.Count == 0)
			{
				return;
			}
			logoTried = true;
			logo = (from g in list
				where ((g is Image || g is RawImage) ? true : false) && Named(g, "logo")
				orderby (Named(g, "shadow") || Named(g, "black")) ? 1 : 0
				select g).ThenByDescending(delegate(Graphic g)
			{
				//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_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)
				Rect rect = g.rectTransform.rect;
				float width = ((Rect)(ref rect)).width;
				rect = g.rectTransform.rect;
				return width * ((Rect)(ref rect)).height;
			}).FirstOrDefault();
			if ((Object)(object)logo == (Object)null)
			{
				Plugin.Log.LogInfo((object)"Menu: no PEAK logo found - no logo glow.");
				return;
			}
			logoColor = logo.color;
			glowAlpha = 0f;
			Sprite val = ((ModConfig.MenuLogoGlow.Value > 0f) ? BlurredShape(logo) : null);
			if ((Object)(object)val != (Object)null)
			{
				GameObject val2 = new GameObject("PEAK Roguelike - Logo Glow", new Type[1] { typeof(RectTransform) });
				val2.transform.SetParent(((Component)logo).transform.parent, false);
				val2.transform.SetSiblingIndex(((Component)logo).transform.GetSiblingIndex());
				RectTransform val3 = (RectTransform)val2.transform;
				RectTransform rectTransform = logo.rectTransform;
				val3.anchorMin = rectTransform.anchorMin;
				val3.anchorMax = rectTransform.anchorMax;
				val3.pivot = rectTransform.pivot;
				val3.anchoredPosition = rectTransform.anchoredPosition;
				val3.sizeDelta = rectTransform.sizeDelta;
				((Transform)val3).localRotation = ((Transform)rectTransform).localRotation;
				((Transform)val3).localScale = ((Transform)rectTransform).localScale * 1.04f;
				glow = val2.AddComponent<Image>();
				glow.sprite = val;
				Image? obj = glow;
				Graphic? obj2 = logo;
				Image val4 = (Image)(object)((obj2 is Image) ? obj2 : null);
				obj.preserveAspect = val4 != null && val4.preserveAspect;
				((Graphic)glow).raycastTarget = false;
				((Graphic)glow).color = Color.clear;
			}
			Plugin.Log.LogInfo((object)("Menu: red glow on '" + ((Object)logo).name + "' (halo " + (((Object)(object)val != (Object)null) ? "built" : "unavailable - tint only") + ")."));
		}

		private static bool Named(Graphic g, string word)
		{
			if (!Has(((Object)g).name))
			{
				Image val = (Image)(object)((g is Image) ? g : null);
				if (val == null || !((Object)(object)val.sprite != (Object)null) || !Has(((Object)val.sprite).name))
				{
					RawImage val2 = (RawImage)(object)((g is RawImage) ? g : null);
					if (val2 != null && (Object)(object)val2.texture != (Object)null)
					{
						return Has(((Object)val2.texture).name);
					}
					return false;
				}
			}
			return true;
			bool Has(string? s)
			{
				if (s != null)
				{
					return s.IndexOf(word, StringComparison.OrdinalIgnoreCase) >= 0;
				}
				return false;
			}
		}

		private static Sprite? BlurredShape(Graphic g)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Expected O, but got Unknown
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			Image val = (Image)(object)((g is Image) ? g : null);
			Texture val2;
			Rect textureRect = default(Rect);
			if (val != null)
			{
				Sprite sprite = val.sprite;
				if (sprite != null)
				{
					val2 = (Texture)(object)sprite.texture;
					textureRect = sprite.textureRect;
					goto IL_00b2;
				}
			}
			RawImage val3 = (RawImage)(object)((g is RawImage) ? g : null);
			if (val3 != null)
			{
				Texture texture = val3.texture;
				if (texture != null)
				{
					val2 = texture;
					Rect uvRect = val3.uvRect;
					float num = ((Rect)(ref uvRect)).x * (float)texture.width;
					uvRect = val3.uvRect;
					float num2 = ((Rect)(ref uvRect)).y * (float)texture.height;
					uvRect = val3.uvRect;
					float num3 = ((Rect)(ref uvRect)).width * (float)texture.width;
					uvRect = val3.uvRect;
					((Rect)(ref textureRect))..ctor(num, num2, num3, ((Rect)(ref uvRect)).height * (float)texture.height);
					goto IL_00b2;
				}
			}
			return null;
			IL_00b2:
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			try
			{
				float num4 = Mathf.Min(1f, 256f / Mathf.Max(((Rect)(ref textureRect)).width, ((Rect)(ref textureRect)).height));
				int num5 = Mathf.Max(8, Mathf.RoundToInt(((Rect)(ref textureRect)).width * num4));
				int num6 = Mathf.Max(8, Mathf.RoundToInt(((Rect)(ref textureRect)).height * num4));
				RenderTexture temporary = RenderTexture.GetTemporary(num5, num6, 0, (RenderTextureFormat)0);
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(((Rect)(ref textureRect)).width / (float)val2.width, ((Rect)(ref textureRect)).height / (float)val2.height);
				Vector2 val5 = default(Vector2);
				((Vector2)(ref val5))..ctor(((Rect)(ref textureRect)).x / (float)val2.width, ((Rect)(ref textureRect)).y / (float)val2.height);
				Graphics.Blit(val2, temporary, val4, val5);
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = temporary;
				Texture2D val6 = new Texture2D(num5, num6, (TextureFormat)4, false);
				val6.ReadPixels(new Rect(0f, 0f, (float)num5, (float)num6), 0, 0);
				val6.Apply();
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				Color32[] pixels = val6.GetPixels32();
				Object.Destroy((Object)(object)val6);
				float[] array = new float[num5 * num6];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = (float)(int)pixels[i].a / 255f;
				}
				int r = Mathf.Max(2, num5 / 40);
				for (int j = 0; j < 3; j++)
				{
					array = BoxBlur(array, num5, num6, r);
				}
				Texture2D val7 = new Texture2D(num5, num6, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				Color32[] array2 = (Color32[])(object)new Color32[num5 * num6];
				for (int k = 0; k < array.Length; k++)
				{
					array2[k] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(Mathf.Clamp01(array[k] * 2.2f) * 255f));
				}
				val7.SetPixels32(array2);
				val7.Apply();
				return Sprite.Create(val7, new Rect(0f, 0f, (float)num5, (float)num6), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Couldn't build the logo glow: " + ex.Message));
				return null;
			}
		}

		private static float[] BoxBlur(float[] src, int w, int h, int r)
		{
			float[] array = new float[src.Length];
			float[] array2 = new float[src.Length];
			float num = 1f / (float)(2 * r + 1);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num2 = 0f;
					for (int k = -r; k <= r; k++)
					{
						num2 += src[i * w + Mathf.Clamp(j + k, 0, w - 1)];
					}
					array[i * w + j] = num2 * num;
				}
			}
			for (int l = 0; l < h; l++)
			{
				for (int m = 0; m < w; m++)
				{
					float num3 = 0f;
					for (int n = -r; n <= r; n++)
					{
						num3 += array[Mathf.Clamp(l + n, 0, h - 1) * w + m];
					}
					array2[l * w + m] = num3 * num;
				}
			}
			return array2;
		}

		private void AnimateLogo()
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			glowAlpha = Mathf.MoveTowards(glowAlpha, 1f, Time.deltaTime / 1.5f);
			if (Time.time >= nextFlicker)
			{
				flicker = ((Random.value < 0.2f) ? Random.Range(0.55f, 0.8f) : 1f);
				nextFlicker = Time.time + ((flicker < 1f) ? Random.Range(0.05f, 0.12f) : Random.Range(0.8f, 3.5f));
			}
			float num = 0.5f + 0.5f * Mathf.Sin(Time.time * 1.6f);
			Color val = default(Color);
			((Color)(ref val))..ctor(1f, 0.32f, 0.26f, logoColor.a);
			logo.color = Color.Lerp(logoColor, val * logoColor, Mathf.Clamp01(ModConfig.MenuLogoTint.Value) * glowAlpha);
			if (!((Object)(object)glow == (Object)null))
			{
				Color color = Color.Lerp(new Color(0.65f, 0.02f, 0.01f), new Color(1f, 0.12f, 0.04f), num);
				color.a = glowAlpha * flicker * Mathf.Clamp01(ModConfig.MenuLogoGlow.Value) * Mathf.Lerp(0.7f, 1f, num);
				((Graphic)glow).color = color;
			}
		}
	}
	internal class Blessing : MonoBehaviour
	{
		private abstract class Option
		{
			public abstract CardSpec Card();

			public abstract void Take(Action<bool> done);
		}

		private sealed class Lane
		{
			public TreeDef Tree;

			public int Level;

			public string Key => "t" + Tree.Id;

			public RelicTrigger Class => ClassOf(Tree.Id);

			public Option? Option(string role)
			{
				int branch = RunState.Branch(Tree.Id);
				int num = Mathf.Min(2, Tree.MaxFor(branch) - Level);
				if (num < 1)
				{
					return null;
				}
				return new TreeOption(Tree, Level, branch, num, role);
			}
		}

		private sealed class TreeOption : Option
		{
			private readonly TreeDef tree;

			private readonly int from;

			private readonly int branch;

			private readonly int add;

			private readonly string role;

			public string Role => role;

			public TreeOption(TreeDef tree, int from, int branch, int add, string role)
			{
				this.tree = tree;
				this.from = from;
				this.branch = branch;
				this.add = add;
				this.role = role;
			}

			private int Target(int br)
			{
				return Mathf.Min(from + add, tree.MaxFor(br));
			}

			private int ForkLevel()
			{
				for (int i = from + 1; i <= from + add; i++)
				{
					if (tree.ForksAt(i, branch))
					{
						return i;
					}
				}
				return 0;
			}

			public override CardSpec Card()
			{
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				int num = Target(branch);
				bool flag = ForkLevel() > 0;
				LevelDef levelDef = tree.At(num, branch);
				Item val = (flag ? null : Offers.Grant(levelDef, Items.Find(Trees.BaseRole(tree.Id))));
				return new CardSpec
				{
					Style = CardStyle.Perk,
					Theme = tree.Theme,
					Title = (flag ? (tree.Name + ": Fork") : levelDef.Name),
					Tag = ((from != 0) ? $"Lv {from} → {num}" : ((num > 1) ? $"New · Lv {num}" : "New")),
					TagColor = Trees.LevelColor(tree.Id, num, branch),
					Body = (flag ? (string.Join("  or  ", from x in Offers.Paths(tree, ForkLevel())
						select x.Name) + "\nChoose your path next.") : CardStats.Tree(tree, levelDef, num, branch)),
					Footer = $"{RoleTag(role)} · {tree.Name} +{num - from}",
					Icon = (Texture?)(object)Items.Icon(val ?? Items.Find(Trees.BaseRole(tree.Id)))
				};
			}

			public override void Take(Action<bool> done)
			{
				int forkAt = ForkLevel();
				if (forkAt == 0)
				{
					Finish(branch);
					done(obj: true);
					return;
				}
				LevelDef[] options = Offers.Paths(tree, forkAt);
				Item baseItem = Items.Find(Trees.BaseRole(tree.Id));
				ChoiceScreen.Show(new ScreenSpec
				{
					Title = "CHOOSE YOUR PATH",
					Subtitle = $"{tree.Name} · level {forkAt}",
					Confirm = "CHOOSE",
					Cards = options.Select((LevelDef o) => CrateCards.ForPath(tree, forkAt, o, baseItem)).ToList(),
					OnConfirm = delegate(int i)
					{
						Finish(options[i].Branch);
						done(obj: true);
					},
					OnBack = delegate
					{
						done(obj: false);
					}
				});
			}

			private void Finish(int br)
			{
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				int num = Target(br);
				RunState.SetLevel(tree.Id, num, br);
				LevelDef levelDef = tree.At(num, br);
				Hud.PickChime();
				Hud.PickBanner($"{tree.Name.ToUpperInvariant()} · LEVEL {num}", levelDef.Name, Trees.LevelColor(tree.Id, num, br));
				Grant(Offers.Grant(levelDef, Items.Find(Trees.BaseRole(tree.Id))));
				Plugin.Log.LogInfo((object)$"Blessing: {tree.Name} {from} -> {num}.");
			}
		}

		private sealed class IngredientOption : Option
		{
			private readonly Recipe recipe;

			private readonly Ingredient ingredient;

			public IngredientOption(Recipe recipe, Ingredient ingredient)
			{
				this.recipe = recipe;
				this.ingredient = ingredient;
			}

			public override CardSpec Card()
			{
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				Item val = Items.Find(ingredient.Gift);
				CardSpec cardSpec = (((Object)(object)val != (Object)null) ? ItemPerkInfo.From(val).ToCard() : new CardSpec
				{
					Style = CardStyle.Perk
				});
				cardSpec.Title = (((Object)(object)val != (Object)null) ? Items.DisplayName(val) : ingredient.Name);
				cardSpec.Tag = "Gift";
				cardSpec.TagColor = Trees.Gold;
				cardSpec.Body = "The last piece of the\n" + recipe.Name + ".";
				cardSpec.Footer = RoleTag("Statue's gift") ?? "";
				return cardSpec;
			}

			public override void Take(Action<bool> done)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				Grant(Items.Find(ingredient.Gift));
				Hud.Banner("THE STATUE GIVES", ingredient.Name, Trees.Gold);
				done(obj: true);
			}
		}

		private sealed class GiftOption : Option
		{
			private readonly Recipe recipe;

			public GiftOption(Recipe recipe)
			{
				this.recipe = recipe;
			}

			public override CardSpec Card()
			{
				return Fusion.ItemCard(recipe, "A gift from the statue");
			}

			public override void Take(Action<bool> done)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				Fusion.Give(recipe);
				Hud.Banner("THE STATUE GIVES", recipe.Name, ChoiceScreen.FusionGlow);
				done(obj: true);
			}
		}

		private sealed class FusionOption : Option
		{
			private readonly Recipe recipe;

			private readonly byte[] slots;

			public FusionOption(Recipe recipe, byte[] slots)
			{
				this.recipe = recipe;
				this.slots = slots;
			}

			public override CardSpec Card()
			{
				return Fusion.Card(recipe, slots);
			}

			public override void Take(Action<bool> done)
			{
				Fusion.Fuse(recipe, slots);
				done(obj: true);
			}
		}

		private const string Gold = "#FFC84F";

		private static Blessing? instance;

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

		private static bool pending;

		private static float pendingAt;

		public static bool On
		{
			get
			{
				if (ModConfig.Blessings.Value)
				{
					return ModConfig.Leveling.Value;
				}
				return false;
			}
		}

		internal static void Install()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("PEAK Roguelike - Blessings");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)61;
			instance = val.AddComponent<Blessing>();
		}

		internal static void Reset()
		{
			blessedStatues.Clear();
			pending = false;
		}

		internal static void FromStatue(int statueViewId)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (On && blessedStatues.Add(statueViewId))
			{
				Hud.Banner("", "The statue blesses you", Trees.Gold);
				pending = true;
				pendingAt = Time.time + 1.5f;
			}
		}

		private void Update()
		{
			if (!pending || Time.time < pendingAt || ChoiceScreen.IsOpen)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null) && !localCharacter.data.dead && !localCharacter.data.passedOut)
			{
				pending = false;
				Show("Revive statue", delegate
				{
				}, delegate
				{
					pending = true;
					pendingAt = Time.time + 8f;
				}, null);
			}
		}

		internal static void DevBless()
		{
			if (!ChoiceScreen.IsOpen)
			{
				Show("Dev blessing", delegate
				{
				}, delegate
				{
				}, null);
			}
		}

		internal static bool TryCrate(Luggage luggage, PerkLuggage perk, Character interactor)
		{
			if (!On || !IsAncient(luggage))
			{
				return false;
			}
			string subtitle = "Ancient Luggage";
			try
			{
				if (!string.IsNullOrEmpty(luggage.GetName()))
				{
					subtitle = luggage.GetName();
				}
			}
			catch
			{
			}
			if (!Show(subtitle, delegate
			{
				luggage.photonView.RPC("RPC_PerkOpen", (RpcTarget)0, Array.Empty<object>());
				perk.ReleaseLock();
				GlobalEvents.TriggerLuggageOpened(luggage, interactor);
			}, delegate
			{
				perk.ReleaseLock();
			}, () => (Object)(object)luggage != (Object)null && !luggage.IsOpen && (Object)(object)Character.localCharacter != (Object)null && Vector3.Distance(Character.localCharacter.Center, luggage.Center()) <= 8f))
			{
				perk.ReleaseLock();
			}
			return true;
		}

		internal static bool IsAncient(Luggage luggage)
		{
			return (luggage.displayName ?? "").ToLowerInvariant().Contains("ancient");
		}

		private static bool Show(string subtitle, Action onTaken, Action onBack, Func<bool>? stillValid)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			List<Option> options = BuildOptions();
			if (options.Count == 0)
			{
				Hud.Toast("The statue is silent", Trees.Gold);
				onTaken();
				return true;
			}
			return ChoiceScreen.Show(new ScreenSpec
			{
				Title = "CHOOSE YOUR BLESSING",
				Subtitle = subtitle,
				Confirm = "ACCEPT",
				BackHint = "Decide later",
				Cards = options.Select((Option o) => o.Card()).ToList(),
				StillValid = stillValid,
				OnConfirm = delegate(int i)
				{
					options[i].Take(delegate(bool ok)
					{
						if (ok)
						{
							onTaken();
						}
						else
						{
							Show(subtitle, onTaken, onBack, stillValid);
						}
					});
				},
				OnBack = onBack
			});
		}

		private static List<Option> BuildOptions()
		{
			List<Option> list = new List<Option>();
			HashSet<string> used = new HashSet<string>();
			List<Lane> source = Lanes();
			Lane top = source.FirstOrDefault();
			if (top == null)
			{
				foreach (TreeDef item in Fresh(null).Take(3))
				{
					list.Add(new TreeOption(item, 0, 0, 1, "New path"));
				}
			}
			else
			{
				Add(top, "Specialize");
				Add(PartnerOf(top), "Partner");
				Add(source.Skip(1).FirstOrDefault((Lane l) => !used.Contains(l.Key) && l.Option("") != null), "Switch lanes");
				if (list.Count < 3)
				{
					foreach (TreeDef item2 in (from t in Fresh(null)
						where ClassOf(t.Id) != top.Class && used.Add("t" + t.Id)
						select t).Take(3 - list.Count))
					{
						list.Add(new TreeOption(item2, 0, 0, 1, "Switch lanes"));
					}
				}
			}
			if (ModConfig.Fusion.Value)
			{
				(Recipe, byte[]) tuple = Fusion.Available().FirstOrDefault();
				if (tuple.Item1 != null)
				{
					list.Add(new FusionOption(tuple.Item1, tuple.Item2));
					goto IL_01fc;
				}
			}
			if (top != null)
			{
				TreeDef treeDef = Fresh(top.Class).FirstOrDefault((TreeDef t) => !used.Contains("t" + t.Id));
				if (treeDef != null)
				{
					list.Add(new TreeOption(treeDef, 0, 0, 1, "Synergy"));
				}
			}
			goto IL_01fc;
			IL_01fc:
			if (ModConfig.Fusion.Value && list.Count > 0)
			{
				int index = Mathf.Max(0, list.FindIndex((Option o) => o is TreeOption treeOption && treeOption.Role == "Specialize"));
				float value = Random.value;
				if (value < ModConfig.StatueFusionChance.Value)
				{
					Recipe recipe = (from _ in Fusion.Recipes
						where _.Result != null && (Object)(object)Items.Find(_.Result) != (Object)null
						orderby Random.value
						select _).FirstOrDefault();
					if (recipe != null)
					{
						list[index] = new GiftOption(recipe);
						Plugin.Log.LogInfo((object)("Blessing: jackpot - " + recipe.Name + "."));
					}
				}
				else if (value < ModConfig.StatueFusionChance.Value + ModConfig.StatueIngredientChance.Value)
				{
					(Recipe, Ingredient)? tuple2 = MissingIngredient();
					if (tuple2.HasValue)
					{
						(Recipe, Ingredient) valueOrDefault = tuple2.GetValueOrDefault();
						list[index] = new IngredientOption(valueOrDefault.Item1, valueOrDefault.Item2);
						Plugin.Log.LogInfo((object)("Blessing: " + valueOrDefault.Item2.Name + " for the " + valueOrDefault.Item1.Name + "."));
					}
				}
			}
			return list;
			void Add(Lane? lane, string role)
			{
				if (lane != null && !used.Contains(lane.Key))
				{
					Option option = lane.Option(role);
					if (option != null)
					{
						used.Add(lane.Key);
						list.Add(option);
					}
				}
			}
		}

		private static (Recipe recipe, Ingredient ingredient)? MissingIngredient()
		{
			Player localPlayer = Player.localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return null;
			}
			List<Item> pockets = (from s in localPlayer.itemSlots
				where s != null && !s.IsEmpty() && (Object)(object)s.prefab != (Object)null
				select s.prefab).ToList();
			(Recipe, Ingredient)? result = null;
			int num = -1;
			foreach (Recipe recipe in Fusion.Recipes)
			{
				if (!recipe.Unlocked() || recipe.Ingredients.Any((Ingredient i) => i.FromTree && !i.Ready()))
				{
					continue;
				}
				List<Ingredient> list = recipe.Ingredients.Where((Ingredient i) => !i.FromTree && !pockets.Any(i.Match)).ToList();
				if (list.Count == 1 && list[0].Gift != null && !((Object)(object)Items.Find(list[0].Gift) == (Object)null))
				{
					int num2 = recipe.Ingredients.Length - 1;
					if (num2 > num)
					{
						num = num2;
						result = (recipe, list[0]);
					}
				}
			}
			return result;
		}

		private static List<Lane> Lanes()
		{
			List<Lane> list = new List<Lane>();
			foreach (TreeDef value in Trees.All.Values)
			{
				int num = RunState.Level(value.Id);
				if (num >= 1)
				{
					list.Add(new Lane
					{
						Tree = value,
						Level = num
					});
				}
			}
			List<Lane> source = list.Where((Lane l) => l.Option("") != null).ToList();
			return source.OrderByDescending((Lane l) => l.Level).ThenBy((Lane _) => Random.value).ToList();
		}

		private static IEnumerable<TreeDef> Fresh(RelicTrigger? cls)
		{
			return from _ in Trees.All.Values
				where RunState.Level(_.Id) == 0 && (!cls.HasValue || ClassOf(_.Id) == cls)
				orderby Random.value
				select _;
		}

		private static Lane? PartnerOf(Lane lane)
		{
			TreeId id = lane.Tree.Id switch
			{
				TreeId.Rope => TreeId.Piton, 
				TreeId.Piton => TreeId.Rope, 
				TreeId.Glider => TreeId.Balloons, 
				TreeId.Balloons => TreeId.Glider, 
				TreeId.Bandage => TreeId.Light, 
				TreeId.Light => TreeId.Bandage, 
				TreeId.SportsDrink => TreeId.Food, 
				TreeId.Food => TreeId.SportsDrink, 
				_ => TreeId.None, 
			};
			TreeDef treeDef = Trees.Get(id);
			if (treeDef != null)
			{
				return new Lane
				{
					Tree = treeDef,
					Level = RunState.Level(id)
				};
			}
			return null;
		}

		internal static RelicTrigger ClassOf(TreeId id)
		{
			switch (id)
			{
			case TreeId.Bandage:
			case TreeId.Light:
				return RelicTrigger.Healing;
			case TreeId.SportsDrink:
			case TreeId.Food:
				return RelicTrigger.Food;
			default:
				return RelicTrigger.Movement;
			}
		}

		private static string RoleTag(string role)
		{
			return "<color=#FFC84F>" + role.ToUpperInvariant() + "</color>";
		}

		private static void Grant(Item? prefab)
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)prefab != (Object)null && (Object)(object)localCharacter != (Object)null)
			{
				GameUtils.instance.InstantiateAndGrab(prefab, localCharacter, 0);
			}
		}
	}
	[HarmonyPatch]
	internal static class BlessingPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(RespawnChest), "SpawnItems")]
		private static bool StatueBlessing(RespawnChest __instance, ref List<PhotonView> __result)
		{
			if (!Blessing.On || !PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			if (Ascents.canReviveDead && Character.PlayerIsDeadOrDown())
			{
				return true;
			}
			__result = new List<PhotonView>();
			Net.Bless(((Luggage)__instance).photonView.ViewID);
			Plugin.Log.LogInfo((object)"Revive statue: nobody to revive - blessing the team.");
			return false;
		}
	}
	internal class BloodMoon : MonoBehaviour
	{
		[HarmonyPatch]
		internal static class Visuals
		{
			private static Image? tint;

			private static Image? vignette;

			private static GameObject? disc;

			private static Material? discMat;

			private static Light? movedMoon;

			private static Quaternion moonLocal;

			private const float EclipseScale = 1.68f;

			private static DayNightManager? moonFor;

			private static Renderer? gameMoon;

			private static readonly string[] MoonColorProps = new string[5] { "_Color", "_BaseColor", "_TintColor", "_EmissionColor", "_MainColor" };

			private static readonly Dictionary<string, Color> moonOriginal = new Dictionary<string, Color>();

			private static Material? moonMat;

			internal static void Tick()
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				float blend = Blend;
				EnsureOverlay();
				float num = Mathf.Clamp01(ModConfig.BmTint.Value) * blend;
				if ((Object)(object)tint != (Object)null)
				{
					((Behaviour)tint).enabled = num > 0.001f;
					((Graphic)tint).color = new Color(0.62f, 0.02f, 0.01f, num);
				}
				if ((Object)(object)vignette != (Object)null)
				{
					((Behaviour)vignette).enabled = num > 0.001f;
					((Graphic)vignette).color = new Color(0.45f, 0f, 0f, Mathf.Clamp01(num * 3.5f));
				}
				if (blend <= 0f && (Object)(object)movedMoon != (Object)null)
				{
					((Component)movedMoon).transform.localRotation = moonLocal;
					movedMoon = null;
				}
			}

			private static void EnsureOverlay()
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				if (!((Object)(object)tint != (Object)null))
				{
					GameObject val = new GameObject("PEAK Roguelike - Blood Filter");
					Object.DontDestroyOnLoad((Object)(object)val);
					Canvas val2 = val.AddComponent<Canvas>();
					val2.renderMode = (RenderMode)0;
					val2.sortingOrder = -50;
					tint = Full(val.transform, "Tint", null);
					vignette = Full(val.transform, "Vignette", VignetteSprite());
					Image? obj = tint;
					bool enabled = (((Behaviour)vignette).enabled = false);
					((Behaviour)obj).enabled = enabled;
				}
			}

			private static Image Full(Transform parent, string name, Sprite? sprite)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Expected O, but got Unknown
				//IL_0034: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: 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)
				GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(parent, false);
				RectTransform val2 = (RectTransform)val.transform;
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				Vector2 offsetMin = (val2.offsetMax = Vector2.zero);
				val2.offsetMin = offsetMin;
				Image val3 = val.AddComponent<Image>();
				val3.sprite = sprite;
				((Graphic)val3).raycastTarget = false;
				return val3;
			}

			private static Sprite VignetteSprite()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				//IL_00ed: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
				Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				for (int i = 0; i < 128; i++)
				{
					for (int j = 0; j < 128; j++)
					{
						float num = ((float)j + 0.5f) / 128f * 2f - 1f;
						float num2 = ((float)i + 0.5f) / 128f * 2f - 1f;
						float num3 = Mathf.Sqrt(num * num + num2 * num2) / 1.414f;
						float num4 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.45f, 1f, num3));
						val.SetPixel(j, i, new Color(1f, 1f, 1f, num4));
					}
				}
				val.Apply();
				return Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f));
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(DayNightManager), "UpdateCycle")]
			private static void Sky(DayNightManager __instance)
			{
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: 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_0110: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Unknown result type (might be due to invalid IL or missing references)
				//IL_0215: Unknown result type (might be due to invalid IL or missing references)
				//IL_021a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0220: Unknown result type (might be due to invalid IL or missing references)
				//IL_0247: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_019a: Unknown result type (might be due to invalid IL or missing references)
				//IL_019f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				if (Application.isPlaying && Ambiance.SkyStrength > 0f)
				{
					try
					{
						AirportSky(__instance, Ambiance.SkyStrength);
						return;
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Airport sky failed: " + ex.Message));
						return;
					}
				}
				float blend = Blend;
				if (blend <= 0f || !Application.isPlaying)
				{
					HideDisc();
					RestoreMoon();
					return;
				}
				try
				{
					Light moon = __instance.moon;
					Light sun = __instance.sun;
					if ((Object)(object)moon == (Object)null || !((Behaviour)moon).enabled)
					{
						Eclipse(sun, blend);
						return;
					}
					Shader.SetGlobalColor("SkyTopColor", Color.Lerp(Shader.GetGlobalColor("SkyTopColor"), new Color(0.1f, 0f, 0.01f), blend * 0.85f));
					Shader.SetGlobalColor("SkyMidColor", Color.Lerp(Shader.GetGlobalColor("SkyMidColor"), new Color(0.32f, 0.02f, 0.02f), blend * 0.85f));
					Shader.SetGlobalColor("SkyBottomColor", Color.Lerp(Shader.GetGlobalColor("SkyBottomColor"), new Color(0.45f, 0.05f, 0.03f), blend * 0.85f));
					Vector3 val = -((Component)moon).transform.forward;
					if (val.y < 0.45f)
					{
						Vector3 forward = default(Vector3);
						((Vector3)(ref forward))..ctor(val.x, 0f, val.z);
						if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
						{
							forward = Vector3.forward;
						}
						Vector3 val2 = ((Vector3)(ref forward)).normalized * Mathf.Cos(0.61086524f) + Vector3.up * Mathf.Sin(0.61086524f);
						val = ((Vector3)(ref val2)).normalized;
					}
					if ((Object)(object)movedMoon == (Object)null)
					{
						movedMoon = moon;
						moonLocal = ((Component)moon).transform.localRotation;
					}
					((Component)moon).transform.localRotation = moonLocal;
					Vector3 val3 = -((Component)moon).transform.forward;
					((Component)moon).transform.rotation = Quaternion.LookRotation(-Vector3.Slerp(val3, val, blend));
					moon.color = Color.Lerp(moon.color, Blood, blend);
					moon.intensity = Mathf.Lerp(moon.intensity, ModConfig.BmMoonLight.Value, blend);
					ShowNightDisc(__instance, val, blend);
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("Blood sky failed: " + ex2.Message));
				}
			}

			private static void AirportSky(DayNightManager dnm, float k)
			{
				//IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: 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_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_0053: 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_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: 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_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_019c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				Shader.SetGlobalColor("SkyTopColor", Color.Lerp(Shader.GetGlobalColor("SkyTopColor"), Ambiance.SkyTop, k));
				Shader.SetGlobalColor("SkyMidColor", Color.Lerp(Shader.GetGlobalColor("SkyMidColor"), Ambiance.SkyMid, k));
				Shader.SetGlobalColor("SkyBottomColor", Color.Lerp(Shader.GetGlobalColor("SkyBottomColor"), Ambiance.SkyBottom, k));
				float lightStrength = Ambiance.LightStrength;
				Color val = default(Color);
				((Color)(ref val))..ctor(1f, 0.3f, 0.2f);
				Color color2;
				if ((Object)(object)dnm.sun != (Object)null)
				{
					Light sun = dnm.sun;
					Color color = dnm.sun.color;
					Color val2 = val;
					color2 = dnm.sun.color;
					sun.color = Color.Lerp(color, val2 * ((Color)(ref color2)).maxColorComponent, lightStrength);
				}
				if ((Object)(object)dnm.moon != (Object)null)
				{
					Light moon = dnm.moon;
					Color color3 = dnm.moon.color;
					Color val3 = val;
					color2 = dnm.moon.color;
					moon.color = Color.Lerp(color3, val3 * ((Color)(ref color2)).maxColorComponent, lightStrength);
				}
				Light val4 = (((Object)(object)dnm.moon != (Object)null && ((Behaviour)dnm.moon).enabled) ? dnm.moon : dnm.sun);
				Vector3 val5 = (((Object)(object)val4 != (Object)null) ? (-((Component)val4).transform.forward) : Vector3.up);
				Vector3 forward = default(Vector3);
				((Vector3)(ref forward))..ctor(val5.x, 0f, val5.z);
				if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
				{
					forward = Vector3.forward;
				}
				if (val5.y < 0.42f)
				{
					Vector3 val6 = ((Vector3)(ref forward)).normalized * Mathf.Cos(0.4886922f) + Vector3.up * Mathf.Sin(0.4886922f);
					val5 = ((Vector3)(ref val6)).normalized;
				}
				ShowDisc(val5, k);
			}

			private static void Eclipse(Light? sun, float b)
			{
				//IL_000a: 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_002a: 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_0052: 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_0072: 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_0092: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				Shader.SetGlobalColor("SkyTopColor", Color.Lerp(Shader.GetGlobalColor("SkyTopColor"), new Color(0.28f, 0.03f, 0.03f), b * 0.8f));
				Shader.SetGlobalColor("SkyMidColor", Color.Lerp(Shader.GetGlobalColor("SkyMidColor"), new Color(0.62f, 0.12f, 0.06f), b * 0.8f));
				Shader.SetGlobalColor("SkyBottomColor", Color.Lerp(Shader.GetGlobalColor("SkyBottomColor"), new Color(0.85f, 0.28f, 0.1f), b * 0.8f));
				if ((Object)(object)sun == (Object)null || !((Behaviour)sun).enabled)
				{
					HideDisc();
					return;
				}
				sun.color = Color.Lerp(sun.color, new Color(1f, 0.34f, 0.2f), b * 0.85f);
				sun.intensity *= Mathf.Lerp(1f, 0.7f, b);
				Vector3 val = -((Component)sun).transform.forward;
				if (val.y > 0f)
				{
					ShowDisc(val, b, eclipse: true);
				}
				else
				{
					HideDisc();
				}
			}

			private static void HideDisc()
			{
				if ((Object)(object)disc != (Object)null && disc.activeSelf)
				{
					disc.SetActive(false);
				}
			}

			private static void ShowNightDisc(DayNightManager dnm, Vector3 lightDir, float b)
			{
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				HideDisc();
				if ((Object)(object)moonFor != (Object)(object)dnm)
				{
					moonFor = dnm;
					RestoreMoon();
					Transform val = (((Object)(object)dnm.earth != (Object)null) ? ((Component)dnm.earth).transform : ((Component)dnm).transform);
					gameMoon = (from r in ((Component)val).GetComponentsInChildren<Renderer>(true)
						where ((Object)r).name.IndexOf("moon", StringComparison.OrdinalIgnoreCase) >= 0 && !(r is ParticleSystemRenderer)
						select r).OrderByDescending(delegate(Renderer r)
					{
						//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_0009: Unknown result type (might be due to invalid IL or missing references)
						//IL_000e: Unknown result type (might be due to invalid IL or missing references)
						Bounds bounds = r.bounds;
						Vector3 extents = ((Bounds)(ref bounds)).extents;
						return ((Vector3)(ref extents)).sqrMagnitude;
					}).FirstOrDefault();
					moonMat = (((Object)(object)gameMoon != (Object)null) ? gameMoon.material : null);
					moonOriginal.Clear();
					if ((Object)(object)moonMat != (Object)null)
					{
						string[] moonColorProps = MoonColorProps;
						foreach (string text in moonColorProps)
						{
							if (moonMat.HasProperty(text))
							{
								moonOriginal[text] = moonMat.GetColor(text);
							}
						}
					}
					ManualLogSource log = Plugin.Log;
					object obj;
					if (!((Object)(object)gameMoon != (Object)null))
					{
						obj = "Blood moon: game moon object not found - only the light turns red.";
					}
					else
					{
						string[] obj2 = new string[7]
						{
							"Blood moon reddens the game's moon '",
							((Object)gameMoon).name,
							"' (",
							null,
							null,
							null,
							null
						};
						Material? obj3 = moonMat;
						object obj4;
						if (obj3 == null)
						{
							obj4 = null;
						}
						else
						{
							Shader shader = obj3.shader;
							obj4 = ((shader != null) ? ((Object)shader).name : null);
						}
						obj2[3] = (string)obj4;
						obj2[4] = "; colours: ";
						obj2[5] = string.Join(", ", moonOriginal.Keys);
						obj2[6] = ").";
						obj = string.Concat(obj2);
					}
					log.LogInfo(obj);
				}
				TintMoon(b);
			}

			private static void TintMoon(float b)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: 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_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)moonMat == (Object)null)
				{
					return;
				}
				foreach (KeyValuePair<string, Color> item in moonOriginal)
				{
					Color value = item.Value;
					Color val = new Color(Blood.r, Blood.g * 0.35f, Blood.b * 0.3f, value.a) * Mathf.Max(0.6f, ((Color)(ref value)).maxColorComponent);
					val.a = value.a;
					moonMat.SetColor(item.Key, Color.Lerp(value, val, b));
				}
			}

			private static void RestoreMoon()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)moonMat == (Object)null)
				{
					return;
				}
				foreach (KeyValuePair<string, Color> item in moonOriginal)
				{
					moonMat.SetColor(item.Key, item.Value);
				}
			}

			internal static void ShowDisc(Vector3 dir, float b, bool eclipse = false, float size = 1f, float distance = 0f)
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Expected O, but got Unknown
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: 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)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				Camera val = Meteors.Eye();
				if ((Object)(object)val == (Object)null)
				{
					HideDisc();
					return;
				}
				if ((Object)(object)disc == (Object)null)
				{
					Shader val2 = Shader.Find("Hidden/Internal-Colored");
					if ((Object)(object)val2 == (Object)null)
					{
						return;
					}
					disc = new GameObject("PEAK Roguelike - Blood Moon Disc");
					Object.DontDestroyOnLoad((Object)(object)disc);
					disc.AddComponent<MeshFilter>().sharedMesh = MoonMesh();
					discMat = new Material(val2);
					discMat.SetInt("_SrcBlend", 5);
					discMat.SetInt("_DstBlend", 10);
					discMat.SetInt("_ZWrite", 0);
					discMat.SetInt("_ZTest", 4);
					discMat.SetInt("_Cull", 0);
					discMat.renderQueue = 2990;
					MeshRenderer val3 = disc.AddComponent<MeshRenderer>();
					((Renderer)val3).sharedMaterial = discMat;
					((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)val3).receiveShadows = false;
				}
				if (!disc.activeSelf)
				{
					disc.SetActive(true);
				}
				float num = Mathf.Min(val.farClipPlane * 0.85f, (distance > 0f) ? distance : 2500f);
				disc.transform.position = ((Component)val).transform.position + dir * num;
				disc.transform.rotation = Quaternion.LookRotation(-dir);
				disc.transform.localScale = Vector3.one * num * 0.075f * (eclipse ? 1.68f : size);
				discMat.SetColor("_Color", eclipse ? new Color(0.42f, 0.1f, 0.08f, b) : new Color(1f, 1f, 1f, b));
			}

			private static Mesh MoonMesh()
			{
				//IL_0006: 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_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d2: Expected O, but got Unknown
				//IL_00ed: 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)
				List<Vector3> list = new List<Vector3> { Vector3.zero };
				List<Color> list2 = new List<Color> { Face(0f, 0f) };
				List<int> list3 = new List<int>();
				for (int i = 1; i <= 28; i++)
				{
					float num = ((i <= 22) ? ((float)i / 22f) : (1f + (float)(i - 22) / 6f * 1.2f));
					for (int j = 0; j < 72; j++)
					{
						float num2 = (float)j / 72f * MathF.PI * 2f;
						list.Add(new Vector3(Mathf.Cos(num2) * num, Mathf.Sin(num2) * num, 0f));
						list2.Add((Color)((i <= 22) ? Face(num, num2) : new Color(1f, 0.12f, 0.08f, 0.28f * Mathf.Pow(1f - (num - 1f) / 1.2f, 2f))));
					}
				}
				for (int k = 0; k < 72; k++)
				{
					list3.Add(0);
					list3.Add(1 + (k + 1) % 72);
					list3.Add(1 + k);
				}
				for (int l = 1; l < 28; l++)
				{
					int num3 = 1 + (l - 1) * 72;
					int num4 = 1 + l * 72;
					for (int m = 0; m < 72; m++)
					{
						int num5 = (m + 1) % 72;
						list3.AddRange(new int[6]
						{
							num3 + m,
							num3 + num5,
							num4 + m,
							num3 + num5,
							num4 + num5,
							num4 + m
						});
					}
				}
				Mesh val = new Mesh
				{
					name = "BloodMoon"
				};
				val.SetVertices(list);
				val.SetColors(list2);
				val.SetTriangles(list3, 0);
				val.RecalculateBounds();
				return val;
			}

			private static Color Face(float rad, float ang)
			{
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				float num = Mathf.Cos(ang) * rad;
				float num2 = Mathf.Sin(ang) * rad;
				float num3 = Mathf.PerlinNoise(num * 1.6f + 3.1f, num2 * 1.6f + 7.7f);
				float num4 = Mathf.PerlinNoise(num * 6f + 11f, num2 * 6f + 5f);
				float num5 = Mathf.Lerp(1f, 0.62f, Mathf.SmoothStep(0.45f, 0.7f, num3)) * Mathf.Lerp(0.9f, 1.05f, num4);
				float num6 = Mathf.Lerp(1f, 0.72f, Mathf.Pow(rad, 3f));
				float num7 = num5 * num6;
				return new Color(1f * num7, 0.2f * num7, 0.13f * num7, 1f);
			}
		}

		internal const string RoomKey = "prl.bm";

		internal const float SafetySeconds = 30f;

		internal static readonly Color Blood = new Color(1f, 0.16f, 0.12f);

		internal static readonly Color Ember = new Color(1f, 0.47f, 0.08f);

		private static BloodMoon? instance;

		private string? seenId;

		private int toastsShown;

		private float nextPoll;

		private DayNightManager? lastDnm;

		private bool wasNight;

		private bool nightfallPending;

		private double safeUntil;

		private double expectStart = -1.0;

		private double endedFor = -1.0;

		private double stagesFor = -1.0;

		private bool huntDone;

		private bool zombiesDone;

		private bool zombiesCleared;

		private bool tornadoDone;

		private bool finalDone;

		private AudioSource? music;

		private AudioClip? musicClip;

		private float musicGain = 1f;

		private bool musicRestart;

		private float previewUntil;

		private float menuBlend;

		private float nextMuteScan;

		private readonly HashSet<AudioSource> muted = new HashSet<AudioSource>();

		private float safeGain = 1f;

		private static float Gap => Mathf.Max(0f, ModConfig.BmWaveGap.Value);

		internal static float WaveFor => Mathf.Max(5f, ModConfig.BmWaveLength.Value);

		internal static float ZombiesAt => Gap;

		internal static float TornadoAt => Gap * 2f;

		internal static float FinalAt => Gap * 3f;

		internal static bool Active { get; private set; }

		internal static int Tier { get; private set; }

		internal static double StartTime { get; private set; }

		internal static string Binder { get; private set; } = "";

		internal static float Blend { get; private set; }

		internal static float Elapsed
		{
			get
			{
				if (!Active)
				{
					return 0f;
				}
				return (float)(PhotonNetwork.Time - StartTime);
			}
		}

		internal static bool GloomRun
		{
			get
			{
				if (MapHandler.Exists)
				{
					return Singleton<MapHandler>.Instance.BiomeIsPresent((BiomeType)8);
				}
				return false;
			}
		}

		internal static bool MesaRun
		{
			get
			{
				if (MapHandler.Exists)
				{
					return Singleton<MapHandler>.Instance.BiomeIsPresent((BiomeType)6);
				}
				return false;
			}
		}

		private static bool InRun
		{
			get
			{
				if ((Object)(object)DayNightManager.instance != (Object)null && (Object)(object)GameUtils.instance != (Object)null && !GameUtils.instance.m_inAirport)
				{
					return MapHandler.Exists;
				}
				return false;
			}
		}

		private static bool IsNight
		{
			get
			{
				if (InRun)
				{
					return DayNightManager.instance.isDay < 0.5f;
				}
				return false;
			}
		}

		internal static void Install()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("PEAK Roguelike - Blood Moon");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)61;
			instance = val.AddComponent<BloodMoon>();
			val.AddComponent<Meteors>();
			((MonoBehaviour)instance).StartCoroutine(instance.LoadMusic());
		}

		internal static float EffectsEnd(int tier)
		{
			return (float)(Mathf.Clamp(tier, 1, 4) - 1) * Gap + WaveFor;
		}

		private void Update()
		{
			Blend = Mathf.MoveTowards(Blend, Active ? 1f : 0f, Time.deltaTime / 6f);
			Visuals.Tick();
			TickMusic();
			if (!(Time.time < nextPoll))
			{
				nextPoll = Time.time + 0.25f;
				ReadRoom();
				if (Active)
				{
					Announce();
				}
				if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
				{
					HostTick();
				}
			}
		}

		private void ReadRoom()
		{
			string text = null;
			if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"prl.bm", out object value) && value is string text2)
			{
				text = text2;
			}
			if (text != null && !InRun)
			{
				text = null;
			}
			if (text == null)
			{
				if (Active)
				{
					Plugin.Log.LogInfo((object)"Blood moon over.");
				}
				Active = false;
				seenId = null;
				return;
			}
			string[] array = text.Split(new char[1] { '|' }, 3);
			if (array.Length >= 2 && int.TryParse(array[0], out var result) && double.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
			{
				bool active = Active;
				Tier = result;
				StartTime = result2;
				Binder = ((array.Length > 2) ? array[2] : "");
				Active = true;
				if (seenId != text)
				{
					seenId = text;
					toastsShown = 0;
					Begin(active);
				}
			}
		}

		private void Begin(bool restart)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)string.Format("Blood moon rises: tier {0}{1}.", Tier, restart ? " (restarted)" : ""));
			Hud.BloodBanner("", "BLOOD MOON", Blood);
			StartMusic(restart);
		}

		private void Announce()
		{
		}

		private void HostTick()
		{
			DayNightManager val = DayNightManager.instance;
			if ((Object)(object)val != (Object)(object)lastDnm)
			{
				lastDnm = val;
				wasNight = IsNight;
			}
			bool isNight = IsNight;
			if (!InRun)
			{
				if (Active)
				{
					SetRoom(null);
				}
				wasNight = false;
				nightfallPending = false;
				return;
			}
			if (!Active)
			{
				if (isNight && !wasNight)
				{
					nightfallPending = true;
				}
				if (!isNight)
				{
					nightfallPending = false;
				}
				if (nightfallPending && PhotonNetwork.Time >= safeUntil)
				{
					nightfallPending = false;
					if (ModConfig.BloodMoon.Value && ModConfig.Relics.Value)
					{
						int num = Mathf.Clamp(RunState.SquadRelics(), 0, 4);
						if (num > 0 && Suns.NightsUnlocked)
						{
							Rise(num, "");
						}
						else
						{
							Plugin.Log.LogInfo((object)((num > 0) ? "Nightfall - this biome's relic isn't taken, a calm night." : "Nightfall - nobody holds a relic, a normal night."));
						}
					}
				}
			}
			else if (StartTime != endedFor && (!(expectStart >= 0.0) || StartTime == expectStart || !(PhotonNetwork.Time - expectStart < 5.0)))
			{
				expectStart = -1.0;
				RunWaves();
				if (Elapsed >= EffectsEnd(Tier))
				{
					End();
				}
			}
			wasNight = isNight;
		}

		private void Rise(int tier, string binder)
		{
			if (Active)
			{
				StopEffects();
			}
			string text = PhotonNetwork.Time.ToString("R", CultureInfo.InvariantCulture);
			expectStart = double.Parse(text, CultureInfo.InvariantCulture);
			endedFor = -1.0;
			SetRoom($"{tier}|{text}|{binder}");
			huntDone = (zombiesDone = (zombiesCleared = (tornadoDone = (finalDone = false))));
			stagesFor = -2.0;
			ReadRoom();
			Plugin.Log.LogInfo((object)((binder.Length > 0) ? $"{binder} bound a relic - blood moon tier {tier}." : $"Nightfall with {tier} relic(s) held - blood moon."));
		}

		private void End()
		{
			endedFor = StartTime;
			SetRoom(null);
			StopEffects();
			safeUntil = PhotonNetwork.Time + 30.0;
			nightfallPending = false;
			Plugin.Log.LogInfo((object)"Blood moon sets.");
		}

		private static void StopEffects()
		{
			ScoutmasterHunt.Stop();
			BloodZombies.Clear();
			Meteors.Stop();
			BloodTornado.KillAll();
		}

		internal static void RelicTaken(string binder)
		{
			if (!((Object)(object)instance == (Object)null) && PhotonNetwork.IsMasterClient)
			{
				((MonoBehaviour)instance).StartCoroutine(instance.RiseForRelic(binder));
			}
		}

		private IEnumerator RiseForRelic(string binder)
		{
			yield return (object)new WaitForSeconds(1.5f);
			if (InRun)
			{
				if (ModConfig.Suns.Value && (!IsNight || !Suns.NightsUnlocked))
				{
					Plugin.Log.LogInfo((object)(binder + " took a relic by day - the sun clears, the blood moon waits for night."));
				}
				else
				{
					Rise(Mathf.Clamp(RunState.SquadRelics(), 1, 4), binder);
				}
			}
		}

		internal static void DarkRite(string who)
		{
			if (!((Object)(object)instance == (Object)null) && PhotonNetwork.IsMasterClient && InRun && ModConfig.BloodMoon.Value && ModConfig.BmDarkRites.Value)
			{
				int num = Mathf.Clamp(RunState.SquadRelics(), 1, 4);
				Plugin.Log.LogInfo((object)string.Format("{0} performed a dark rite - blood {1} at tier {2}.", who, IsNight ? "moon" : "eclipse", num));
				instance.nightfallPending = false;
				instance.Rise(num, who);
			}
		}

		private void RunWaves()
		{
			float elapsed = Elapsed;
			if (stagesFor != StartTime)
			{
				bool flag = stagesFor == -2.0;
				stagesFor = StartTime;
				if (!flag)
				{
					huntDone = elapsed > 1f;
					zombiesDone = elapsed > ZombiesAt + 1f;
					zombiesCleared = false;
					tornadoDone = elapsed > TornadoAt + 1f;
					finalDone = elapsed > FinalAt + 1f;
				}
			}
			if (!huntDone)
			{
				huntDone = true;
				if (ModConfig.BmScoutmaster.Value)
				{
					ScoutmasterHunt.Steer(WaveFor - elapsed);
				}
			}
			if (Tier >= 2 && !zombiesDone && elapsed >= ZombiesAt)
			{
				zombiesDone = true;
				if (ModConfig.BmZombies.Value)
				{
					BloodZombies.Spawn(ModConfig.BmZombieCount.Value, ZombiesAt + WaveFor - elapsed);
				}
			}
			if (Tier >= 3 && !tornadoDone && elapsed >= TornadoAt)
			{
				tornadoDone = true;
				if (ModConfig.BmTornado.Value)
				{
					BloodTornado.Spawn(TornadoAt + WaveFor - elapsed);
				}
			}
			if (Tier >= 4 && !finalDone && elapsed >= FinalAt)
			{
				finalDone = true;
				float seconds = FinalAt + WaveFor - elapsed;
				if (GloomRun ? ModConfig.BmGlassMeteors.Value : ModConfig.BmMeteors.Value)
				{
					Meteors.Begin(seconds);
				}
			}
			BloodZombies.HostTick();
		}

		private static void SetRoom(string? value)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
			{
				PhotonNetwork.CurrentRoom.SetCustomProperties(new Hashtable { [(object)"prl.bm"] = value }, (Hashtable)null, (WebFlags)null);
			}
		}

		internal static void DevStart(int tier)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)instance == (Object)null) && PhotonNetwork.IsMasterClient)
			{
				if (tier <= 0)
				{
					SetRoom(null);
					StopEffects();
					Hud.Toast("Blood moon ended (dev)", Blood);
					return;
				}
				if (!InRun)
				{
					Hud.Toast("Start a run first", Blood);
					return;
				}
				DayNightManager val = DayNightManager.instance;
				float num = val.dayEnd + 0.05f;
				val.setTimeOfDay(num);
				val.photonView.RPC("RPCA_SyncTime", (RpcTarget)0, new object[2] { val.dayCount, num });
				instance.wasNight = true;
				instance.nightfallPending = false;
				instance.Rise(Mathf.Clamp(tier, 1, 4), "");
			}
		}

		private IEnumerator LoadMusic()
		{
			string path = Path.GetDirectoryName(typeof(BloodMoon).Assembly.Location) ?? "";
			Dictionary<string, AudioType> types = new Dictionary<string, AudioType>
			{
				[".ogg"] = (AudioType)14,
				[".wav"] = (AudioType)20,
				[".mp3"] = (AudioType)13
			};
			List<string> source = (Directory.Exists(path) ? (from f in Directory.GetFiles(path)
				where types.ContainsKey(Path.GetExtension(f).ToLowerInvariant())
				orderby (!(Path.GetFileNameWithoutExtension(f).Replace(" ", "").ToLowerInvariant() == "bloodmoon")) ? 1 : 0, f
				select f).ToList() : new List<string>());
			using (IEnumerator<string> enumerator = source.Take(1).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					string path2 = enumerator.Current;
					AudioType val = types[Path.GetExtension(path2).ToLowerInvariant()];
					UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(new Uri(path2).AbsoluteUri, val);
					try
					{
						yield return req.SendWebRequest();
						if ((int)req.result != 1)
						{
							Plugin.Log.LogWarning((object)("Couldn't load blood moon music " + path2 + ": " + req.error));
							yield break;
						}
						musicClip = DownloadHandlerAudioClip.GetContent(req);
						Plugin.Log.LogInfo((object)$"Blood moon music loaded: {Path.GetFileName(path2)} ({musicClip.length:0}s).");
						yield break;
					}
					finally
					{
						((IDisposable)req)?.Dispose();
					}
				}
			}
			Plugin.Log.LogInfo((object)"No .ogg/.wav/.mp3 next to the DLL - blood moons play without music.");
		}

		private void EnsureMusicSource()
		{
			if ((Object)(object)music == (Object)null)
			{
				music = ((Component)this).gameObject.AddComponent<AudioSource>();
				music.spatialBlend = 0f;
				music.playOnAwake = false;
			}
			if ((Object)(object)music.outputAudioMixerGroup == (Object)null)
			{
				music.outputAudioMixerGroup = Meteors.MixerGroup("Music");
				Plugin.Log.LogInfo((object)(((Object)(object)music.outputAudioMixerGroup != (Object)null) ? ("Blood moon music plays through the game's '" + ((Object)music.outputAudioMixerGroup).name + "' channel.") : "Blood moon music: game Music channel not found - the in-game music slider won't affect it."));
			}
		}

		internal static void DevPreviewMusic()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.musicClip == (Object)null)
			{
				Hud.Toast("No blood moon music loaded", ChoiceScreen.Cream);
				return;
			}
			instance.EnsureMusicSource();
			if (!instance.music.isPlaying)
			{
				instance.musicGain = 1f;
				instance.PlayFromTop();
			}
			instance.previewUntil = Time.time + 10f;
		}

		private void StartMusic(bool restart)
		{
			if (!((Object)(object)musicClip == (Object)null))
			{
				EnsureMusicSource();
				if (restart && music.isPlaying)
				{
					musicRestart = true;
					return;
				}
				musicRestart = false;
				musicGain = 1f;
				PlayFromTop();
			}
		}

		private void PlayFromTop()
		{
			music.clip = musicClip;
			music.loop = ModConfig.BmMusicLoop.Value;
			music.volume = 0f;
			music.Play();
		}

		private void TickMenuMusic()
		{
			bool flag = Ambiance.InMenu && ModConfig.MenuMusic.Value && (Object)(object)musicClip != (Object)null;
			menuBlend = Mathf.MoveTowards(menuBlend, flag ? 1f : 0f, Time.deltaTime / (flag ? 2.5f : 1f));
			if (flag)
			{
				EnsureMusicSource();
				if (!music.isPlaying)
				{
					musicGain = 1f;
					PlayFromTop();
					music.loop = true;
				}
				if (Time.time >= nextMuteScan)
				{
					nextMuteScan = Time.time + 0.5f;
					MuteGameMusic();
				}
			}
			else
			{
				if (muted.Count <= 0)
				{
					return;
				}
				foreach (AudioSource item in muted)
				{
					if ((Object)(object)item != (Object)null)
					{
						item.mute = false;
					}
				}
				muted.Clear();
			}
		}

		private void MuteGameMusic()
		{
			AudioSource[] array = Object.FindObjectsByType<AudioSource>((FindObjectsSortMode)0);
			foreach (AudioSource val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)music || !val.isPlaying || val.mute)
				{
					continue;
				}
				AudioMixerGroup outputAudioMixerGroup = val.outputAudioMixerGroup;
				if (!((Object)(object)outputAudioMixerGroup == (Object)null) && ((Object)outputAudioMixerGroup).name.IndexOf("music", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val.mute = true;
					if (muted.Add(val))
					{
						Plugin.Log.LogInfo((object)("Menu: muted the game's music '" + ((Object)val).name + "' for the blood moon song."));
					}
				}
			}
		}

		private void TickMusic()
		{
			TickMenuMusic();
			if ((Object)(object)music == (Object)null)
			{
				return;
			}
			if (musicRestart)
			{
				musicGain = Mathf.MoveTowards(musicGain, 0f, Time.deltaTime / 0.75f);
				if (musicGain <= 0f)
				{
					musicRestart = false;
					PlayFromTop();
				}
			}
			else
			{
				musicGain = Mathf.MoveTowards(musicGain, 1f, Time.deltaTime / 1.5f);
			}
			safeGain = Mathf.MoveTowards(safeGain, (Sanctuary.LocalSafe && menuBlend <= 0f) ? 0f : 1f, Time.deltaTime / 2.5f);
			if (music.isPlaying)
			{
				bool flag = Time.time < previewUntil;
				music.volume = ModConfig.BmMusicVolume.Value * (flag ? 1f : (Mathf.Max(Blend, menuBlend) * safeGain)) * musicGain;
				if (!Active && Blend <= 0f && !flag && menuBlend <= 0f)
				{
					music.Stop();
				}
			}
		}
	}
	internal static class Squad
	{
		private static readonly Dictionary<int, float> veiledUntil = new Dictionary<int, float>();

		internal const float M = 0.625f;

		public static bool Solo
		{
			get
			{
				if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
				{
					return PhotonNetwork.CurrentRoom.PlayerCount <= 1;
				}
				return true;
			}
		}

		public static float Aura => Mathf.Max(1f, ModConfig.BmRelicAura.Value) * 0.625f;

		public static List<Character> Alive()
		{
			return Character.AllCharacters.Where((Character c) => (Object)(object)c != (Object)null && (Object)(object)c.data != (Object)null && !c.isBot && !c.isZombie && !c.data.isScoutmaster && !c.data.dead).ToList();
		}

		public static List<Character> Hunted()
		{
			return (from c in Alive()
				where !Sanctuary.Safe(c)
				select c).ToList();
		}

		public static List<Character> Pursued()
		{
			return (from c in Hunted()
				where !Veiled(c)
				select c).ToList();
		}

		public static void Veil(int actor, float seconds)
		{
			if (!(seconds <= 0f))
			{
				veiledUntil[actor] = Time.time + seconds;
				Character val = ((IEnumerable<Character>)Alive()).FirstOrDefault((Func<Character, bool>)((Character x) => (Object)(object)((MonoBehaviourPun)x).photonView != (Object)null && ((MonoBehaviourPun)x).photonView.Owner != null && ((MonoBehaviourPun)x).photonView.Owner.ActorNumber == actor));
				Plugin.Log.LogInfo((object)$"Relic veil: {(((Object)(object)val != (Object)null) ? val.characterName : $"player {actor}")} hidden for {seconds:0.#}s.");
			}
		}

		public static bool Veiled(Character c)
		{
			if ((Object)(object)((MonoBehaviourPun)c).photonView != (Object)null && ((MonoBehaviourPun)c).photonView.Owner != null && veiledUntil.TryGetValue(((MonoBehaviourPun)c).photonView.Owner.ActorNumber, out var value))
			{
				return Time.time < value;
			}
			return false;
		}

		public static Character? Of(Player p)
		{
			return ((IEnumerable<Character>)Alive()).FirstOrDefault((Func<Character, bool>)((Character c) => (Object)(object)((MonoBehaviourPun)c).photonView != (Object)null && ((MonoBehaviourPun)c).photonView.Owner == p));
		}

		public static bool AnyHolders()
		{
			return RunState.RelicHolders().Any<(Player, int)>(((Player player, int count) h) => h.count > 0);
		}

		public static List<Character> Holders()
		{
			return (from h in RunState.RelicHolders()
				where h.count > 0
				select Of(h.player) into c
				where (Object)(object)c != (Object)null && !Sanctuary.Safe(c) && !Veiled(c)
				select (c)).ToList();
		}

		public static List<Character> Marked()
		{
			List<Character> list = Pursued();
			if (!AnyHolders())
			{
				return list;
			}
			List<Character> holders = Holders();
			float aura = Aura;
			return list.Where((Character c) => holders.Contains(c) || holders.Any((Character h) => Vector3.Distance(h.Center, c.Center) <= aura)).ToList();
		}

		public static bool Grouped(Character holder)
		{
			float aura = Aura;
			return Alive().Any((Character o) => (Object)(object)o != (Object)(object)holder && Vector3.Distance(o.Center, holder.Center) <= aura);
		}

		public static Vector3? SafeGround(Vector3 around, float min, float max, float reach, List<Character> alive, float safe)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 24; i++)
			{
				Vector3? p = GroundNear(around, min, max, reach);
				if (p.HasValue && alive.All((Character c) => Vector3.Distance(c.Center, p.Value) >= safe))
				{
					return p;
				}
			}
			return null;
		}

		public static Vector3? GroundNear(Vector3 around, float min, float max, float reach)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_004b: 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_005a: 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_0081: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val2 = default(Vector3);
			RaycastHit val3 = default(RaycastHit);
			for (int i = 0; i < 16; i++)
			{
				Vector2 insideUnitCircle = Random.insideUnitCircle;
				Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized * Random.Range(min, max);
				((Vector3)(ref val2))..ctor(around.x + val.x, around.y + reach, around.z + val.y);
				if (Physics.Raycast(val2, Vector3.down, ref val3, reach * 2f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1) && ((RaycastHit)(ref val3)).normal.y > 0.55f)
				{
					return ((RaycastHit)(ref val3)).point + Vector3.up * 1.2f;
				}
			}
			return null;
		}
	}
	internal static class BloodZombies
	{
		private static readonly List<MushroomZombie> spawned = new List<MushroomZombie>();

		private static float until;

		private static string? prefab;

		private static float nextSafeCheck;

		private static string Prefab()
		{
			if (prefab != null)
			{
				return prefab;
			}
			string[] array = new string[4] { "MushroomZombie", "MushroomZombie_NPC", "Zombie_NPC", "Zombie" };
			foreach (string text in array)
			{
				GameObject val = Resources.Load<GameObject>(text);
				if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<MushroomZombie>() != (Object)null)
				{
					return prefab = text;
				}
			}
			MushroomZombieSpawner val2 = ((IEnumerable<MushroomZombieSpawner>)Resources.FindObjectsOfTypeAll<MushroomZombieSpawner>()).FirstOrDefault((Func<MushroomZombieSpawner, bool>)((MushroomZombieSpawner s) => (Object)(object)s.mushroomZombiePrefab != (Object)null));
			prefab = (((Object)(object)val2 != (Object)null) ? ((Object)((Component)val2.mushroomZombiePrefab).gameObject).name : "MushroomZombie_Player");
			Plugin.Log.LogInfo((object)("Blood moon zombie prefab: " + prefab));
			return prefab;
		}

		public static void Spawn(int count, float seconds)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			List<Character> list = Squad.Alive();
			if (list.Count == 0 || count <= 0)
			{
				return;
			}
			until = Time.time + seconds;
			float num = Mathf.Max(5f, ModConfig.BmZombieSafe.Value) * 0.625f;
			Vector3 center = list.OrderByDescending((Character c) => c.Center.y).First().Center;
			Vector3 center2 = list.OrderBy((Character c) => c.Center.y).First().Center;
			Vector3? val = AheadAnchor();
			int num2 = Mathf.CeilToInt((float)count / 2f);
			int num3 = 0;
			int num4 = 0;
			for (int num5 = 0; num5 < count; num5++)
			{
				Vector3? val2 = null;
				Vector3? val3;
				if (num5 < num2)
				{
					if (val.HasValue)
					{
						Vector3 valueOrDefault = val.GetValueOrDefault();
						val2 = Squad.SafeGround(valueOrDefault, 2f, 14f, 25f, list, num) ?? Squad.SafeGround(valueOrDefault + Vector3.up * num * 0.5f, num * 0.4f, num, num, list, num);
					}
					val3 = val2;
					if (!val3.HasValue)
					{
						val2 = Squad.SafeGround(center + Vector3.up * num * 0.7f, num * 0.5f, num * 1.2f, num, list, num);
					}
					if (val2.HasValue)
					{
						num4++;
					}
				}
				val3 = val2;
				if (!val3.HasValue)
				{
					val2 = Squad.SafeGround(center2 + Vector3.down * num * 0.6f, num * 0.6f, num * 1.3f, num, list, num) ?? Squad.SafeGround(center2, num, num * 1.8f, num * 1.5f, list, num);
				}
				if (!val2.HasValue)
				{
					continue;
				}
				try
				{
					GameObject val4 = PhotonNetwork.Instantiate(Prefab(), val2.Value, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f), (byte)0, (object[])null);
					MushroomZombie component = val4.GetComponent<MushroomZombie>();
					if (!((Object)(object)component == (Object)null))
					{
						spawned.Add(component);
						((MonoBehaviour)component).StartCoroutine(Wake(component));
						num3++;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Zombie spawn failed: " + ex.Message));
					break;
				}
			}
			Plugin.Log.LogInfo((object)string.Format("Blood moon: {0} zombies rose ({1:0}s; {2} {3}, rest below; none within {4:0}m).", num3, seconds, num4, (!val.HasValue) ? "above the squad" : "at the camp ahead", num / 0.625f));
		}

		private static Vector3? AheadAnchor()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			//IL_002e: 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_0093: 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)
			try
			{
				MapHandler instance = Singleton<MapHandler>.Instance;
				int num = (int)MapHandler.CurrentSegmentNumber;
				if (num < instance.segments.Length)
				{
					GameObject segmentCampfire = instance.segments[num].segmentCampfire;
					if (segmentCampfire != null)
					{
						return segmentCampfire.transform.position;
					}
				}
				PeakSequence val = ((IEnumerable<PeakSequence>)Resources.FindObjectsOfTypeAll<PeakSequence>()).FirstOrDefault((Func<PeakSequence, bool>)delegate(PeakSequence p)
				{
					//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)
					if ((Object)(object)p != (Object)null)
					{
						Scene scene = ((Component)p).gameObject.scene;
						return ((Scene)(ref scene)).IsValid();
					}
					return false;
				});
				if ((Object)(object)val != (Object)null)
				{
					return ((Object)(object)val.ropeSpawnPoint != (Object)null) ? val.ropeSpawnPoint.position : ((Component)val).transform.position;
				}
				if ((Object)(object)instance.respawnThePeak != (Object)null)
				{
					return instance.respawnThePeak.position;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("No campfire ahead for the zombies: " + ex.Message));
			}
			return null;
		}

		private static IEnumerator Wake(MushroomZombie z)
		{
			yield return (object)new WaitForSeconds(1.6f);
			if (!((Object)(object)z == (Object)null) && (int)z.currentState == 0)
			{
				z.WakeUpFromSleep();
				Character val = (from c in Squad.Pursued()
					orderby Vector3.Distance(c.Center, z.character.Center)
					select c).FirstOrDefault();
				if ((Object)(object)val != (Object)null)
				{
					z.SetCurrentTarget(val, 15f);
				}
			}
		}

		public static void HostTick()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (spawned.Count == 0)
			{
				return;
			}
			if (Time.time >= until)
			{
				Clear();
			}
			else
			{
				if (Time.time < nextSafeCheck)
				{
					return;
				}
				nextSafeCheck = Time.time + 0.5f;
				List<Character> source = Squad.Pursued();
				for (int num = spawned.Count - 1; num >= 0; num--)
				{
					MushroomZombie z = spawned[num];
					if ((Object)(object)z == (Object)null)
					{
						spawned.RemoveAt(num);
					}
					else if (((MonoBehaviourPun)z).photonView.IsMine && !((Object)(object)z.character == (Object)null))
					{
						try
						{
							if (Sanctuary.Safe(z.character.Center))
							{
								z.currentState = (State)6;
								z.DestroyZombie();
								spawned.RemoveAt(num);
								Plugin.Log.LogInfo((object)"Blood moon zombie crumbled on safe ground.");
							}
							else if ((Object)(object)z.currentTarget != (Object)null && (Sanctuary.Safe(z.currentTarget) || Squad.Veiled(z.currentTarget)))
							{
								Character val = source.OrderBy((Character c) => Vector3.Distance(c.Center, z.character.Center)).FirstOrDefault();
								z.SetCurrentTarget(val, ((Object)(object)val != (Object)null) ? 15f : 0f);
							}
						}
						catch (Exception ex)
						{
							Plugin.Log.LogWarning((object)("Zombie safe-ground check failed: " + ex.Message));
						}
					}
				}
			}
		}

		public static void Clear()
		{
			foreach (MushroomZombie item in spawned)
			{
				if (!((Object)(object)item == (Object)null) && ((MonoBehaviourPun)item).photonView.IsMine)
				{
					try
					{
						item.currentState = (State)6;
						item.DestroyZombie();
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Zombie despawn failed: " + ex.Message));
					}
				}
			}
			if (spawned.Count > 0)
			{
				Plugin.Log.LogInfo((object)"Blood moon zombies crumbled.");
			}
			spawned.Clear();
		}
	}
	internal class BloodTornado : MonoBehaviour
	{