Decompiled source of PeakStalker v1.0.5

BepInEx/plugins/PeakStalker/PeakStalker.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PeakStalker;

internal sealed class AirportColorGrade
{
	private GameObject root;

	private Volume volume;

	private VolumeProfile profile;

	private bool fallback;

	private float level;

	internal void Capture()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: 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_013d: Unknown result type (might be due to invalid IL or missing references)
		Restore();
		root = new GameObject("PeakStalker_AirportRedGrade");
		volume = root.AddComponent<Volume>();
		volume.isGlobal = true;
		volume.priority = 10000f;
		volume.weight = 0f;
		profile = ScriptableObject.CreateInstance<VolumeProfile>();
		ColorAdjustments val = profile.Add<ColorAdjustments>(true);
		((VolumeParameter<Color>)(object)val.colorFilter).value = new Color(1f, 0.55f, 0.45f);
		((VolumeParameter<float>)(object)val.postExposure).value = -0.65f;
		((VolumeParameter<float>)(object)val.saturation).value = -10f;
		((VolumeParameter<float>)(object)val.contrast).value = 4f;
		volume.sharedProfile = profile;
		Camera main = Camera.main;
		UniversalAdditionalCameraData val2 = (Object.op_Implicit((Object)(object)main) ? ((Component)main).GetComponent<UniversalAdditionalCameraData>() : null);
		if (Object.op_Implicit((Object)(object)val2))
		{
			LayerMask volumeLayerMask = val2.volumeLayerMask;
			int value = ((LayerMask)(ref volumeLayerMask)).value;
			for (int i = 0; i < 32; i++)
			{
				if ((value & (1 << i)) != 0)
				{
					root.layer = i;
					break;
				}
			}
		}
		int num;
		if (Object.op_Implicit((Object)(object)val2) && val2.renderPostProcessing)
		{
			LayerMask volumeLayerMask2 = val2.volumeLayerMask;
			num = ((((LayerMask)(ref volumeLayerMask2)).value == 0) ? 1 : 0);
		}
		else
		{
			num = 1;
		}
		fallback = (byte)num != 0;
	}

	internal void Apply(float progress)
	{
		level = progress;
		if (Object.op_Implicit((Object)(object)volume))
		{
			volume.weight = progress;
		}
	}

	internal void DrawFallback()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		if (fallback && !(level <= 0f))
		{
			Color color = GUI.color;
			GUI.color = new Color(0.11f, 0.005f, 0.004f, level * 0.22f);
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
		}
	}

	internal void Restore()
	{
		level = 0f;
		if (Object.op_Implicit((Object)(object)root))
		{
			Object.Destroy((Object)(object)root);
		}
		if (Object.op_Implicit((Object)(object)profile))
		{
			foreach (VolumeComponent component in profile.components)
			{
				if (Object.op_Implicit((Object)(object)component))
				{
					Object.Destroy((Object)(object)component);
				}
			}
			Object.Destroy((Object)(object)profile);
		}
		root = null;
		volume = null;
		profile = null;
		fallback = false;
	}
}
internal sealed class AirportDecay
{
	private sealed class Lamp
	{
		internal Light light;

		internal float intensity;

		internal bool enabled;

		internal Color color;
	}

	private readonly List<GameObject> overlays = new List<GameObject>();

	private readonly List<Lamp> lamps = new List<Lamp>();

	private readonly FleshSurface flesh = new FleshSurface();

	private readonly FleshSurface visceral = new FleshSurface();

	private readonly List<Mesh> projected = new List<Mesh>();

	private Material tissue;

	private Material rawTissue;

	private bool captured;

	private float ambientIntensity;

	private float reflectionIntensity;

	private float fogDensity;

	private Color ambientLight;

	private Color fogColor;

	private AmbientMode ambientMode;

	private bool fog;

	internal void Capture(Vector3 center, IList<Renderer> excluded)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_049d: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a4: Expected O, but got Unknown
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Expected O, but got Unknown
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Expected O, but got Unknown
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Invalid comparison between Unknown and I4
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_039b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
		if (captured)
		{
			Restore();
		}
		captured = true;
		ambientIntensity = RenderSettings.ambientIntensity;
		reflectionIntensity = RenderSettings.reflectionIntensity;
		ambientLight = RenderSettings.ambientLight;
		ambientMode = RenderSettings.ambientMode;
		fog = RenderSettings.fog;
		fogDensity = RenderSettings.fogDensity;
		fogColor = RenderSettings.fogColor;
		try
		{
			Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0);
			foreach (Light val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && ((Behaviour)val).enabled && ((int)val.type == 1 || Vector3.Distance(((Component)val).transform.position, center) < 65f))
				{
					lamps.Add(new Lamp
					{
						light = val,
						intensity = val.intensity,
						enabled = ((Behaviour)val).enabled,
						color = val.color
					});
				}
			}
			Shader val2 = Shader.Find("Universal Render Pipeline/Lit");
			if (!Object.op_Implicit((Object)(object)val2))
			{
				throw new Exception("Airport flesh overlay shader unavailable");
			}
			tissue = new Material(val2);
			((Object)tissue).name = "PeakStalker_WetAirportTissue";
			tissue.SetFloat("_Surface", 1f);
			tissue.SetFloat("_SrcBlend", 5f);
			tissue.SetFloat("_DstBlend", 10f);
			tissue.SetFloat("_ZWrite", 0f);
			tissue.SetFloat("_ZTest", 4f);
			tissue.SetFloat("_Smoothness", 0.72f);
			tissue.SetFloat("_BumpScale", 0.65f);
			tissue.SetColor("_BaseColor", Color.white);
			tissue.SetOverrideTag("RenderType", "Transparent");
			tissue.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			tissue.renderQueue = 3000;
			flesh.Prepare();
			flesh.BindOverlay(tissue);
			rawTissue = new Material(tissue);
			((Object)rawTissue).name = "PeakStalker_RawBlisteredTissue";
			rawTissue.SetFloat("_Smoothness", 0.88f);
			rawTissue.SetFloat("_BumpScale", 0.95f);
			visceral.Prepare(visceral: true);
			visceral.BindOverlay(rawTissue);
			MeshRenderer[] array2 = Object.FindObjectsByType<MeshRenderer>((FindObjectsSortMode)0);
			Array.Sort(array2, delegate(MeshRenderer a, MeshRenderer b)
			{
				//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_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				Bounds bounds3 = ((Renderer)a).bounds;
				Vector3 val7 = ((Bounds)(ref bounds3)).center - center;
				float sqrMagnitude = ((Vector3)(ref val7)).sqrMagnitude;
				Bounds bounds4 = ((Renderer)b).bounds;
				Vector3 val8 = ((Bounds)(ref bounds4)).center - center;
				return sqrMagnitude.CompareTo(((Vector3)(ref val8)).sqrMagnitude);
			});
			MeshRenderer[] array3 = array2;
			foreach (MeshRenderer val3 in array3)
			{
				if (!WorldSurfaceFilter.Eligible(val3))
				{
					continue;
				}
				Bounds bounds = ((Renderer)val3).bounds;
				if (Vector3.Distance(((Bounds)(ref bounds)).center, center) > 150f || excluded.Contains((Renderer)(object)val3))
				{
					continue;
				}
				MeshFilter component = ((Component)val3).GetComponent<MeshFilter>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.sharedMesh))
				{
					continue;
				}
				bool flag = true;
				bool flag2 = true;
				Material[] sharedMaterials = ((Renderer)val3).sharedMaterials;
				foreach (Material material in sharedMaterials)
				{
					if (!WorldSurfaceFilter.MaterialEligible(material))
					{
						flag = false;
					}
					if (!WorldSurfaceFilter.SecondaryEligible(material))
					{
						flag2 = false;
					}
				}
				if (!flag && !flag2)
				{
					continue;
				}
				Bounds bounds2 = ((Renderer)val3).bounds;
				Vector3 size = ((Bounds)(ref bounds2)).size;
				float num3 = Mathf.Min(size.x, Mathf.Min(size.y, size.z));
				float num4 = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
				float num5 = size.x + size.y + size.z - num3 - num4;
				bool flag3 = !flag || (num5 > 3f && num3 < num5 * 0.25f) || !component.sharedMesh.HasVertexAttribute((VertexAttribute)4);
				if (overlays.Count >= 600)
				{
					break;
				}
				Mesh val4 = component.sharedMesh;
				if (flag3)
				{
					try
					{
						val4 = ProjectedTissueMesh.Build(val4, ((Component)val3).transform);
						projected.Add(val4);
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("Tissue projection fallback for " + ((Object)val3).name + ": " + ex.Message));
					}
				}
				GameObject val5 = new GameObject("PeakStalker_AirportFleshLayer");
				overlays.Add(val5);
				val5.layer = ((Component)val3).gameObject.layer;
				val5.transform.SetParent(((Component)val3).transform, false);
				val5.AddComponent<MeshFilter>().sharedMesh = val4;
				MeshRenderer val6 = val5.AddComponent<MeshRenderer>();
				Material[] array4 = (Material[])(object)new Material[val4.subMeshCount];
				for (int num6 = 0; num6 < array4.Length; num6++)
				{
					array4[num6] = (flag3 ? rawTissue : tissue);
				}
				((Renderer)val6).sharedMaterials = array4;
				((Renderer)val6).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val6).receiveShadows = true;
			}
			Debug.Log((object)("Airport flesh: " + overlays.Count + " scenery overlays, original materials retained."));
		}
		catch
		{
			Restore();
			throw;
		}
	}

	internal void Apply(float progress, bool lightsOut, bool roomDecay)
	{
		if (captured)
		{
			float progress2 = (roomDecay ? Mathf.Clamp01(progress) : 0f);
			flesh.Apply(progress2);
			visceral.Apply(progress2);
		}
	}

	internal void ApplyLighting(float progress, bool lightsOut)
	{
		//IL_0078: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: 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)
		if (!captured)
		{
			return;
		}
		float num = (lightsOut ? Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(progress * 1.5f)) : 0f);
		foreach (Lamp lamp in lamps)
		{
			if (Object.op_Implicit((Object)(object)lamp.light))
			{
				lamp.light.intensity = lamp.intensity * (1f - num * 0.35f);
				lamp.light.color = Color.Lerp(lamp.color, new Color(0.8f, 0.25f, 0.16f), num);
				((Behaviour)lamp.light).enabled = lamp.enabled;
			}
		}
		if (lightsOut && num > 0f)
		{
			RenderSettings.ambientMode = (AmbientMode)3;
			RenderSettings.ambientIntensity = Mathf.Lerp(ambientIntensity, 0.4f, num);
			RenderSettings.ambientLight = Color.Lerp(ambientLight, new Color(0.32f, 0.12f, 0.09f), num);
			RenderSettings.reflectionIntensity = reflectionIntensity * (1f - num * 0.4f);
		}
	}

	internal void Restore()
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: 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)
		if (!captured)
		{
			return;
		}
		foreach (Lamp lamp in lamps)
		{
			if (Object.op_Implicit((Object)(object)lamp.light))
			{
				lamp.light.intensity = lamp.intensity;
				((Behaviour)lamp.light).enabled = lamp.enabled;
				lamp.light.color = lamp.color;
			}
		}
		foreach (GameObject overlay in overlays)
		{
			if (Object.op_Implicit((Object)(object)overlay))
			{
				overlay.SetActive(false);
				Object.Destroy((Object)(object)overlay);
			}
		}
		overlays.Clear();
		if (Object.op_Implicit((Object)(object)tissue))
		{
			Object.Destroy((Object)(object)tissue);
		}
		tissue = null;
		flesh.Restore();
		if (Object.op_Implicit((Object)(object)rawTissue))
		{
			Object.Destroy((Object)(object)rawTissue);
		}
		rawTissue = null;
		visceral.Restore();
		foreach (Mesh item in projected)
		{
			if (Object.op_Implicit((Object)(object)item))
			{
				Object.Destroy((Object)(object)item);
			}
		}
		projected.Clear();
		RenderSettings.ambientIntensity = ambientIntensity;
		RenderSettings.ambientLight = ambientLight;
		RenderSettings.ambientMode = ambientMode;
		RenderSettings.reflectionIntensity = reflectionIntensity;
		RenderSettings.fog = fog;
		RenderSettings.fogDensity = fogDensity;
		RenderSettings.fogColor = fogColor;
		lamps.Clear();
		captured = false;
	}
}
internal sealed class AirportSoundscape
{
	private ConfigEntry<float> volume;

	private GameObject root;

	private AudioSource source;

	private AudioClip clip;

	internal void Initialize(ConfigFile config)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		volume = config.Bind<float>("Audio", "AirportAmbienceVolume", 0.38f, new ConfigDescription("Supplied heartbeat ambience during the airport event.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
	}

	internal void Begin(Transform parent)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		Restore();
		root = new GameObject("PeakStalker_AirportAmbience");
		root.transform.SetParent(parent, false);
		source = root.AddComponent<AudioSource>();
		source.playOnAwake = false;
		source.loop = true;
		source.spatialBlend = 0f;
		source.priority = 48;
		clip = HorrorAudio.Clip(HorrorAudio.Ambience(), "Supplied airport heartbeat ambience");
		source.clip = clip;
		source.volume = 0f;
		source.Play();
	}

	internal void Apply(float level)
	{
		if (Object.op_Implicit((Object)(object)source))
		{
			source.volume = volume.Value * level;
		}
	}

	internal void Restore()
	{
		if (Object.op_Implicit((Object)(object)root))
		{
			AudioRetire.Fade(root, 2.5f, (AudioClip[])(object)new AudioClip[1] { clip });
		}
		else if (Object.op_Implicit((Object)(object)clip))
		{
			Object.Destroy((Object)(object)clip);
		}
		root = null;
		source = null;
		clip = null;
	}
}
public sealed class AudioRetire : MonoBehaviour
{
	private AudioSource[] sources;

	private float[] volumes;

	private AudioClip[] clips;

	private float started;

	private float duration;

	internal static void Fade(GameObject root, float seconds, AudioClip[] owned)
	{
		if (Object.op_Implicit((Object)(object)root))
		{
			root.transform.SetParent((Transform)null, true);
			Object.DontDestroyOnLoad((Object)(object)root);
			AudioRetire audioRetire = root.AddComponent<AudioRetire>();
			audioRetire.sources = root.GetComponentsInChildren<AudioSource>();
			audioRetire.volumes = new float[audioRetire.sources.Length];
			for (int i = 0; i < audioRetire.sources.Length; i++)
			{
				audioRetire.volumes[i] = audioRetire.sources[i].volume;
			}
			audioRetire.clips = owned;
			audioRetire.started = Time.unscaledTime;
			audioRetire.duration = Mathf.Max(0.1f, seconds);
		}
	}

	private void Update()
	{
		float num = Mathf.Clamp01((Time.unscaledTime - started) / duration);
		float num2 = 1f - Mathf.SmoothStep(0f, 1f, num);
		for (int i = 0; i < sources.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)sources[i]))
			{
				sources[i].volume = volumes[i] * num2;
			}
		}
		if (num >= 1f)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}

	private void OnDestroy()
	{
		if (clips == null)
		{
			return;
		}
		AudioClip[] array = clips;
		foreach (AudioClip val in array)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				Object.Destroy((Object)(object)val);
			}
		}
	}
}
internal static class AudioSynthesis
{
	internal const int SampleRate = 22050;

	internal static float[] Generate(bool arrival)
	{
		double num = (arrival ? 3.5 : 0.5);
		float[] array = new float[(int)(num * 22050.0)];
		Random random = new Random(arrival ? 4041 : 414);
		double num2 = 0.0;
		for (int i = 0; i < array.Length; i++)
		{
			double num3 = (double)i / 22050.0;
			num2 = 0.65 * num2 + 0.35 * (2.0 * random.NextDouble() - 1.0);
			double num10;
			if (arrival)
			{
				double num4 = Math.Min(1.0, num3 / 0.018) * Math.Min(1.0, (num - num3) / 0.4);
				double num5 = Math.Exp((0.0 - num3) / 0.34) * (1.0 - Math.Exp((0.0 - num3) / 0.008));
				double num6 = Math.Pow(Math.Sin(Math.PI * num3 / num), 0.8);
				double num7 = Math.Sin(Math.PI * 2.0 * (154.0 * num3 - 8.0 * num3 * num3));
				double num8 = Math.Sin(Math.PI * 2.0 * (308.0 * num3 - 16.0 * num3 * num3));
				double num9 = Math.Sin(Math.PI * 2.0 * (69.0 * num3 - 2.0 * num3 * num3));
				num10 = num4 * (num5 * (0.75 * num2 + 0.45 * Math.Sin(Math.PI * 420.0 * num3)) + num6 * (0.34 * num7 + 0.18 * num8 + 0.25 * num9 + 0.12 * num2) * (0.85 + 0.15 * Math.Sin(20.734511513692635 * num3)));
			}
			else
			{
				num10 = Pulse(num3 - 0.025, 1.0, num2) + Pulse(num3 - 0.225, 0.76, num2);
				num10 *= Math.Min(1.0, num3 / 0.004) * Math.Min(1.0, (num - num3) / 0.035);
			}
			array[i] = (float)num10;
		}
		double num11 = 0.0;
		float[] array2 = array;
		foreach (float num12 in array2)
		{
			num11 += (double)num12;
		}
		num11 /= (double)array.Length;
		double num13 = 0.0;
		for (int k = 0; k < array.Length; k++)
		{
			num13 = Math.Max(num13, Math.Abs((double)array[k] - num11));
		}
		if (num13 > 0.0)
		{
			for (int l = 0; l < array.Length; l++)
			{
				double num14 = (double)l / 22050.0;
				double val = Math.Min(1.0, num14 / 0.003) * Math.Min(1.0, (num - num14 - 4.5351473922902495E-05) / 0.012);
				array[l] = (float)(((double)array[l] - num11) * (0.92 / num13) * Math.Max(0.0, val));
			}
		}
		return array;
	}

	private static double Pulse(double t, double gain, double noise)
	{
		if (t < 0.0)
		{
			return 0.0;
		}
		double num = (1.0 - Math.Exp((0.0 - t) / 0.004)) * Math.Exp((0.0 - t) / 0.052);
		double num2 = 0.48 * Math.Sin(Math.PI * 144.0 * t) + 0.36 * Math.Sin(Math.PI * 288.0 * t) + 0.24 * Math.Sin(Math.PI * 432.0 * t);
		double num3 = 0.14 * noise * Math.Exp((0.0 - t) / 0.018);
		return gain * (num * num2 + num3);
	}
}
internal static class BeachWarningClock
{
	internal static int Remaining(double until, double now)
	{
		return (int)Math.Ceiling(Math.Max(0.0, Math.Min(600.0, until - now)));
	}

	internal static float Fade(double start, double until, double now)
	{
		if (now < start || now >= until + 4.0)
		{
			return 0f;
		}
		return (float)Math.Min(1.0, Math.Min((now - start) / 0.8, (until + 4.0 - now) / 2.0));
	}
}
public sealed class BeachWarning : MonoBehaviour
{
	internal const string StartKey = "peakStalker.headStartStart.v9";

	internal const string UntilKey = "peakStalker.headStartUntil.v9";

	private ConfigEntry<bool> show;

	private GUIStyle title;

	private GUIStyle text;

	private object room;

	private double start;

	private double until;

	private bool visible;

	internal void Initialize(ConfigFile config)
	{
		show = config.Bind<bool>("Warnings", "BeachCountdown", true, "Show a fading warning during the unlocked run's actual head start. Shared host deadline; does not change pursuit timing.");
	}

	internal static void Publish(float duration)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
		{
			double time = PhotonNetwork.Time;
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)(object)val).Add((object)"peakStalker.headStartStart.v9", (object)time);
			((Dictionary<object, object>)(object)val).Add((object)"peakStalker.headStartUntil.v9", (object)(time + (double)duration));
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}

	internal static void Clear()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
		{
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)(object)val).Add((object)"peakStalker.headStartStart.v9", (object)0.0);
			((Dictionary<object, object>)(object)val).Add((object)"peakStalker.headStartUntil.v9", (object)0.0);
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}

	internal static double GetOrPublish(float duration)
	{
		if (PhotonNetwork.InRoom && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.headStartStart.v9", out object value) && value is double && (double)value > 0.0 && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.headStartUntil.v9", out object value2) && value2 is double && !double.IsNaN((double)value2) && !double.IsInfinity((double)value2) && (double)value2 >= (double)value)
		{
			return (double)value2;
		}
		double result = PhotonNetwork.Time + (double)duration;
		Publish(duration);
		return result;
	}

	private void Update()
	{
		visible = false;
		Character localCharacter = Character.localCharacter;
		if (show == null || !show.Value || !PhotonNetwork.InRoom || !Object.op_Implicit((Object)(object)localCharacter) || localCharacter.inAirport || localCharacter.gameOver || !HauntedSession.Unlocked)
		{
			return;
		}
		if (!object.ReferenceEquals(room, PhotonNetwork.CurrentRoom))
		{
			room = PhotonNetwork.CurrentRoom;
			start = (until = 0.0);
		}
		if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.headStartStart.v9", out object value) && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.headStartUntil.v9", out object value2) && value is double && value2 is double)
		{
			start = (double)value;
			until = (double)value2;
			if (!double.IsNaN(start) && !double.IsNaN(until) && !double.IsInfinity(start) && !double.IsInfinity(until) && !(start <= 0.0) && !(until < start) && !(until - start > 600.01))
			{
				visible = BeachWarningClock.Fade(start, until, PhotonNetwork.Time) > 0f;
			}
		}
	}

	private void OnGUI()
	{
		//IL_028d: 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_012b: 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_006e: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		if (!visible)
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if (!Object.op_Implicit((Object)(object)localCharacter) || localCharacter.inAirport || localCharacter.gameOver || !HauntedSession.Unlocked)
		{
			return;
		}
		double time = PhotonNetwork.Time;
		float num = BeachWarningClock.Fade(start, until, time);
		if (num <= 0f)
		{
			return;
		}
		if (title == null)
		{
			title = new GUIStyle(GUI.skin.label);
			title.alignment = (TextAnchor)4;
			title.fontStyle = (FontStyle)1;
			this.text = new GUIStyle(title);
			this.text.fontStyle = (FontStyle)0;
		}
		float num2 = Mathf.Clamp((float)Screen.height / 1080f, 0.65f, 1.5f);
		title.fontSize = Mathf.RoundToInt(26f * num2);
		this.text.fontSize = Mathf.RoundToInt(19f * num2);
		title.normal.textColor = new Color(1f, 0.68f, 0.61f);
		this.text.normal.textColor = new Color(0.98f, 0.92f, 0.86f);
		int num3 = BeachWarningClock.Remaining(until, time);
		string text = ((num3 > 0) ? "IT FOLLOWED YOU." : "YOUR HEAD START IS OVER.");
		string text2 = ((num3 > 0) ? ("You have " + num3 + " seconds to run before it starts chasing.") : "Keep moving.");
		Color color = GUI.color;
		int depth = GUI.depth;
		try
		{
			GUI.depth = -100;
			float num4 = (float)Screen.height * 0.17f;
			GUI.color = new Color(0f, 0f, 0f, num * 0.85f);
			GUI.Label(new Rect(2f, num4 + 2f, (float)Screen.width, 40f * num2), text, title);
			GUI.Label(new Rect(2f, num4 + 40f * num2 + 2f, (float)Screen.width, 32f * num2), text2, this.text);
			GUI.color = new Color(1f, 1f, 1f, num);
			GUI.Label(new Rect(0f, num4, (float)Screen.width, 40f * num2), text, title);
			GUI.Label(new Rect(0f, num4 + 40f * num2, (float)Screen.width, 32f * num2), text2, this.text);
		}
		finally
		{
			GUI.color = color;
			GUI.depth = depth;
		}
	}
}
public sealed class BingBongIntro : MonoBehaviour
{
	private ConfigEntry<bool> enabledSetting;

	private ConfigEntry<float> volume;

	private AudioSource voice;

	private AudioClip clip;

	private object room;

	private double played = -1.0;

	private float nextMouth;

	private BingBongMouth mouth;

	private float originalOffset;

	private float originalMultiplier;

	private bool broken;

	internal void Initialize(ConfigFile config)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		enabledSetting = config.Bind<bool>("BingBong", "OpeningLine", true, "Play the supplied recording once at the start of the haunted beach run, tied to the shared head-start clock.");
		volume = config.Bind<float>("BingBong", "VoiceVolume", 0.85f, new ConfigDescription("Opening recording volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
	}

	private void Update()
	{
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		if (broken || enabledSetting == null)
		{
			return;
		}
		try
		{
			Character localCharacter = Character.localCharacter;
			if (!PhotonNetwork.InRoom || !Object.op_Implicit((Object)(object)localCharacter) || localCharacter.inAirport || localCharacter.gameOver || !enabledSetting.Value || !HauntedSession.Unlocked)
			{
				Stop();
				if (!PhotonNetwork.InRoom)
				{
					room = null;
					played = -1.0;
				}
				return;
			}
			if (!object.ReferenceEquals(room, PhotonNetwork.CurrentRoom))
			{
				Stop();
				room = PhotonNetwork.CurrentRoom;
				played = -1.0;
			}
			if (!Plugin.RigReady(localCharacter) || localCharacter.data.dead || localCharacter.IsGhost)
			{
				Stop();
				return;
			}
			if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.headStartStart.v9", out object value) && value is double num)
			{
				double num2 = PhotonNetwork.Time - num;
				if (num > 0.0 && num != played && !double.IsNaN(num) && !double.IsInfinity(num) && num2 >= 0.0)
				{
					played = num;
					if (num2 < (double)HorrorAudio.BingBong().Length / 22050.0)
					{
						Play((float)num2);
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)voice) || !voice.isPlaying)
			{
				ReleaseMouth();
				return;
			}
			voice.volume = volume.Value;
			if (Object.op_Implicit((Object)(object)mouth) || !(Time.unscaledTime >= nextMouth))
			{
				return;
			}
			nextMouth = Time.unscaledTime + 0.5f;
			float num3 = 625f;
			BingBongMouth[] array = Object.FindObjectsByType<BingBongMouth>((FindObjectsSortMode)0);
			foreach (BingBongMouth val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && ((Behaviour)val).isActiveAndEnabled && Object.op_Implicit((Object)(object)val.audioSource) && Object.op_Implicit((Object)(object)val.animator))
				{
					Vector3 val2 = ((Component)val).transform.position - localCharacter.Center;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num3)
					{
						mouth = val;
						num3 = sqrMagnitude;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)mouth))
			{
				originalOffset = mouth.timeOffset;
				originalMultiplier = mouth.timeMultiplier;
				mouth.timeOffset = voice.time;
				mouth.timeMultiplier = 1f / Mathf.Max(0.05f, Mathf.Abs(mouth.audioSource.pitch));
				mouth.SampleAudioClip(clip);
			}
		}
		catch (Exception ex)
		{
			broken = true;
			Stop();
			Debug.LogWarning((object)("Bing Bong opening line disabled safely: " + ex.Message));
		}
	}

	private void Play(float offset)
	{
		if (!Object.op_Implicit((Object)(object)clip))
		{
			clip = HorrorAudio.Clip(HorrorAudio.BingBong(), "Supplied Bing Bong opening line");
		}
		if (!Object.op_Implicit((Object)(object)voice))
		{
			voice = ((Component)this).gameObject.AddComponent<AudioSource>();
			voice.playOnAwake = false;
			voice.loop = false;
			voice.spatialBlend = 0f;
			voice.dopplerLevel = 0f;
			voice.priority = 24;
		}
		ReleaseMouth();
		voice.clip = clip;
		voice.volume = volume.Value;
		voice.pitch = 1f;
		voice.time = Mathf.Clamp(offset, 0f, Mathf.Max(0f, clip.length - 0.1f));
		voice.Play();
		nextMouth = 0f;
		Debug.Log((object)"Bing Bong opening recording started with the beach head start.");
	}

	private void ReleaseMouth()
	{
		if (Object.op_Implicit((Object)(object)mouth))
		{
			mouth.canPlay = false;
			mouth.timeOffset = originalOffset;
			mouth.timeMultiplier = originalMultiplier;
			if (Object.op_Implicit((Object)(object)mouth.animator))
			{
				mouth.animator.SetFloat(mouth.animValue, 0f);
			}
		}
		mouth = null;
	}

	private void Stop()
	{
		if (Object.op_Implicit((Object)(object)voice) && voice.isPlaying)
		{
			voice.volume = Mathf.MoveTowards(voice.volume, 0f, Time.unscaledDeltaTime / 0.35f);
			if (voice.volume < 0.001f)
			{
				voice.Stop();
			}
		}
		ReleaseMouth();
	}

	private void OnDestroy()
	{
		Stop();
		if (Object.op_Implicit((Object)(object)voice))
		{
			Object.Destroy((Object)(object)voice);
		}
		if (Object.op_Implicit((Object)(object)clip))
		{
			Object.Destroy((Object)(object)clip);
		}
	}
}
internal sealed class CampfireWard
{
	private readonly List<Campfire> fires = new List<Campfire>();

	private float nextScan;

	private Campfire beach;

	internal void Scan()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < nextScan)
		{
			return;
		}
		nextScan = Time.time + 1f;
		fires.Clear();
		beach = null;
		Campfire[] array = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0);
		foreach (Campfire val in array)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				if ((int)val.advanceToSegment == 0)
				{
					beach = val;
				}
				else if (val.Lit)
				{
					fires.Add(val);
				}
			}
		}
	}

	internal bool Protects(Vector3 point, float radius)
	{
		//IL_002c: 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)
		Scan();
		foreach (Campfire fire in fires)
		{
			if (Object.op_Implicit((Object)(object)fire) && fire.Lit && Inside(point, fire.Center(), radius))
			{
				return true;
			}
		}
		return false;
	}

	private static bool Inside(Vector3 p, Vector3 fire, float radius)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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)
		Vector3 val = p - fire;
		if (Mathf.Abs(val.y) < 8f)
		{
			Vector2 val2 = new Vector2(val.x, val.z);
			return ((Vector2)(ref val2)).sqrMagnitude < radius * radius;
		}
		return false;
	}

	internal bool Steer(Vector3 position, Vector3 target, float radius, out Vector3 goal)
	{
		//IL_0008: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00fb: 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_00fd: 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_010f: 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_0111: 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_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: 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_009d: 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_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_0145: 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_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: 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_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		Scan();
		goal = target;
		Vector3 val6 = default(Vector3);
		foreach (Campfire fire in fires)
		{
			if (!Object.op_Implicit((Object)(object)fire) || !fire.Lit)
			{
				continue;
			}
			Vector3 val = fire.Center();
			Vector3 val2 = position - val;
			val2.y = 0f;
			if (Mathf.Abs(position.y - val.y) >= 8f)
			{
				continue;
			}
			if (((Vector3)(ref val2)).sqrMagnitude < (radius + 2f) * (radius + 2f))
			{
				if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
				{
					val2 = position - target;
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
					{
						val2 = Vector3.back;
					}
				}
				goal = val + ((Vector3)(ref val2)).normalized * (radius + 3f);
				goal.y = position.y;
				return true;
			}
			Vector3 val3 = target - val;
			val3.y = 0f;
			Vector3 val4 = val3 - val2;
			float num = ((((Vector3)(ref val4)).sqrMagnitude > 0.01f) ? Mathf.Clamp01((0f - Vector3.Dot(val2, val4)) / ((Vector3)(ref val4)).sqrMagnitude) : 0f);
			Vector3 val5 = val2 + val4 * num;
			if (((Vector3)(ref val5)).sqrMagnitude < (radius + 2f) * (radius + 2f))
			{
				if (Inside(target, val, radius))
				{
					goal = val + ((Vector3)(ref val2)).normalized * (radius + 3f);
					goal.y = position.y;
					return true;
				}
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				((Vector3)(ref val6))..ctor(0f - normalized.z, 0f, normalized.x);
				if (Vector3.Dot(val6, val4) < 0f)
				{
					val6 = -val6;
				}
				goal = position + val6 * 6f + normalized * 2f;
				return true;
			}
		}
		return false;
	}

	internal void Reset()
	{
		fires.Clear();
		beach = null;
		nextScan = 0f;
	}
}
internal static class EmergencyRecoveryPolicy
{
	internal static bool Needed(bool eligible, float nearest, float belowLowest, bool transition, bool visible, float now, float retryAt, float extreme)
	{
		if (!eligible || float.IsNaN(nearest) || float.IsInfinity(nearest) || now < retryAt)
		{
			return false;
		}
		if (nearest > extreme || belowLowest > 120f)
		{
			return true;
		}
		if (transition && !visible)
		{
			if (!(nearest > 100f))
			{
				return belowLowest > 40f;
			}
			return true;
		}
		return false;
	}
}
internal static class EventEnvelope
{
	internal static float Level(float elapsed, float rise, float total)
	{
		float num = Mathf.Max(total, rise + 20f);
		float num2 = Mathf.Clamp((num - elapsed) / 16f, 0f, 1f);
		float num3 = Mathf.Clamp((elapsed - 4f) / rise, 0f, 1f);
		return Mathf.SmoothStep(0f, 1f, num3) * Mathf.SmoothStep(0f, 1f, num2);
	}

	internal static float Duration(float rise, float total)
	{
		return Mathf.Max(total, rise + 20f);
	}
}
internal sealed class FleshSurface
{
	private sealed class Layer
	{
		internal Texture2D texture;

		internal Color32[] original;

		internal Color32[] frame;

		internal bool overlay;
	}

	private sealed class Binding
	{
		internal Material material;

		internal string property;

		internal Texture original;

		internal Layer layer;

		internal Texture bump;

		internal bool normalKeyword;
	}

	private const int Size = 128;

	private readonly Dictionary<Texture, Layer> cache = new Dictionary<Texture, Layer>();

	private Layer blank;

	private readonly List<Layer> layers = new List<Layer>();

	private readonly List<Binding> bindings = new List<Binding>();

	private Color32[] flesh;

	private Color32[] normalFull;

	private Color32[] normalFrame;

	private float[] spread;

	private float[] weights;

	private Texture2D normal;

	internal void Prepare(bool visceral = false)
	{
		//IL_037e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Unknown result type (might be due to invalid IL or missing references)
		//IL_063c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0646: Expected O, but got Unknown
		//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_058d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0592: Unknown result type (might be due to invalid IL or missing references)
		//IL_0596: Unknown result type (might be due to invalid IL or missing references)
		//IL_059b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0600: Unknown result type (might be due to invalid IL or missing references)
		//IL_0605: Unknown result type (might be due to invalid IL or missing references)
		flesh = (Color32[])(object)new Color32[16384];
		spread = new float[flesh.Length];
		weights = new float[flesh.Length];
		float[] array = new float[flesh.Length];
		for (int i = 0; i < 128; i++)
		{
			for (int j = 0; j < 128; j++)
			{
				float num = (float)((double)j * Math.PI * 2.0 / 128.0);
				float num2 = (float)((double)i * Math.PI * 2.0 / 128.0);
				float num3 = num + (float)Math.Sin((double)(num2 * 2f) + Math.Sin(num * 3f)) * 0.35f;
				float num4 = num2 + (float)Math.Sin((double)(num * 3f) + Math.Sin(num2 * 2f)) * 0.32f;
				float num5 = (float)(Math.Sin((double)(num3 * 5f) + Math.Sin(num4 * 3f) * 2.0 + Math.Sin(num3 * 2f - num4) * 1.2) * Math.Sin(num4 * 4f + num3));
				float num6 = (float)(0.5 + 0.25 * Math.Sin((double)(num * 2f) + Math.Sin(num2 * 2f)) + 0.25 * Math.Sin(num2 * 3f - num));
				float num7 = (float)(Math.Sin(num * 27f + num2 * 19f) * Math.Sin(num2 * 23f - num * 13f));
				float num8 = Mathf.Pow(Mathf.Max(0f, 1f - Mathf.Abs((float)Math.Sin((double)(num * 4f) + Math.Sin(num2 * 3f) * 1.7)) * 15f), 2f);
				float num9 = Mathf.Pow(Mathf.Max(0f, 1f - Mathf.Abs((float)Math.Sin((double)(num2 * 7f) + Math.Sin(num * 2f) * 2.0)) * 23f), 2f) * num6;
				float num10 = Mathf.Pow(Mathf.Max(0f, num5), 3f);
				float num11 = Mathf.Max(num8, num9);
				int num12 = i * 128 + j;
				spread[num12] = num6 * 0.65f;
				array[num12] = num10 * 0.55f + num6 * 0.17f + num7 * 0.006f - num11 * 0.14f;
				ref Color32 reference = ref flesh[num12];
				reference = new Color32((byte)Mathf.Clamp(135f + num6 * 65f + num10 * 24f - num11 * 72f + num7 * 7f, 0f, 255f), (byte)Mathf.Clamp(27f + num6 * 29f + num10 * 12f - num11 * 24f + num7 * 4f, 0f, 255f), (byte)Mathf.Clamp(35f + num6 * 25f + num10 * 8f - num11 * 17f + num7 * 3f, 0f, 255f), byte.MaxValue);
				if (visceral)
				{
					float num13 = Mathf.Pow(Mathf.Max(0f, (float)(Math.Cos((double)(num3 * 3f) + Math.Sin(num4 * 2f)) * Math.Cos((double)(num4 * 4f) + Math.Sin(num3)))), 2f);
					float num14 = Mathf.Clamp01(num11 * 1.6f);
					array[num12] = num13 * 0.8f + num10 * 0.24f - num14 * 0.24f + num7 * 0.008f;
					ref Color32 reference2 = ref flesh[num12];
					reference2 = new Color32((byte)Mathf.Clamp(150f + num13 * 75f + num6 * 22f - num14 * 95f, 0f, 255f), (byte)Mathf.Clamp(21f + num13 * 61f + num6 * 12f - num14 * 18f, 0f, 255f), (byte)Mathf.Clamp(43f + num13 * 24f + num6 * 16f - num14 * 21f, 0f, 255f), byte.MaxValue);
				}
			}
		}
		normalFull = (Color32[])(object)new Color32[flesh.Length];
		normalFrame = (Color32[])(object)new Color32[flesh.Length];
		for (int k = 0; k < 128; k++)
		{
			for (int l = 0; l < 128; l++)
			{
				float num15 = (array[k * 128 + (l + 1) % 128] - array[k * 128 + (l + 128 - 1) % 128]) * 2.5f;
				float num16 = (array[(k + 1) % 128 * 128 + l] - array[(k + 128 - 1) % 128 * 128 + l]) * 2.5f;
				Vector3 val = new Vector3(0f - num15, 0f - num16, 1f);
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				byte b = (byte)(128f + normalized.x * 127f);
				byte b2 = (byte)(128f + normalized.y * 127f);
				byte b3 = (byte)(128f + normalized.z * 127f);
				ref Color32 reference3 = ref normalFull[k * 128 + l];
				reference3 = new Color32(byte.MaxValue, b2, b3, b);
			}
		}
		normal = new Texture2D(128, 128, (TextureFormat)4, true, true);
		((Object)normal).name = "PeakStalker_FleshNormals";
		((Texture)normal).wrapMode = (TextureWrapMode)0;
		Apply(0f);
	}

	internal bool Bind(Material material, Material original)
	{
		string text = (material.HasProperty("_BaseMap") ? "_BaseMap" : (material.HasProperty("_MainTex") ? "_MainTex" : null));
		if (text == null)
		{
			return false;
		}
		Texture val = (original.HasProperty("_BaseMap") ? original.GetTexture("_BaseMap") : (original.HasProperty("_MainTex") ? original.GetTexture("_MainTex") : null));
		if (val is RenderTexture)
		{
			return false;
		}
		Layer value;
		if (Object.op_Implicit((Object)(object)val))
		{
			if (!cache.TryGetValue(val, out value))
			{
				value = Create(val);
				cache.Add(val, value);
			}
		}
		else
		{
			if (blank == null)
			{
				blank = Create(null);
			}
			value = blank;
		}
		bindings.Add(new Binding
		{
			material = material,
			property = text,
			original = val,
			layer = value,
			bump = (original.HasProperty("_BumpMap") ? original.GetTexture("_BumpMap") : null),
			normalKeyword = original.IsKeywordEnabled("_NORMALMAP")
		});
		return true;
	}

	internal void BindOverlay(Material material)
	{
		if (blank == null)
		{
			blank = Create(null);
		}
		blank.overlay = true;
		material.SetTexture("_BaseMap", (Texture)(object)blank.texture);
		material.SetTexture("_BumpMap", (Texture)(object)normal);
		material.EnableKeyword("_NORMALMAP");
		Apply(0f);
	}

	private Layer Create(Texture source)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: 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_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		Layer layer = new Layer();
		layer.original = (Color32[])(object)new Color32[16384];
		if (Object.op_Implicit((Object)(object)source))
		{
			RenderTexture active = RenderTexture.active;
			RenderTexture temporary = RenderTexture.GetTemporary(128, 128, 0, (RenderTextureFormat)0);
			Texture2D val = null;
			try
			{
				Graphics.Blit(source, temporary);
				RenderTexture.active = temporary;
				val = new Texture2D(128, 128, (TextureFormat)4, false);
				val.ReadPixels(new Rect(0f, 0f, 128f, 128f), 0, 0);
				val.Apply(false, false);
				layer.original = val.GetPixels32();
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
		else
		{
			for (int i = 0; i < layer.original.Length; i++)
			{
				ref Color32 reference = ref layer.original[i];
				reference = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			}
		}
		layer.frame = (Color32[])layer.original.Clone();
		layer.texture = new Texture2D(128, 128, (TextureFormat)4, true);
		((Object)layer.texture).name = "PeakStalker_SpreadingFlesh";
		((Texture)layer.texture).wrapMode = (TextureWrapMode)(Object.op_Implicit((Object)(object)source) ? ((int)source.wrapMode) : 0);
		Write(layer.texture, layer.frame);
		layers.Add(layer);
		return layer;
	}

	internal void Apply(float progress)
	{
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)normal == (Object)null)
		{
			return;
		}
		progress = Mathf.Clamp01(progress);
		foreach (Binding binding in bindings)
		{
			if (!Object.op_Implicit((Object)(object)binding.material))
			{
				continue;
			}
			binding.material.SetTexture(binding.property, (Texture)((progress > 0f) ? ((object)binding.layer.texture) : ((object)binding.original)));
			if (binding.material.HasProperty("_BumpMap"))
			{
				binding.material.SetTexture("_BumpMap", (Texture)((progress > 0f) ? ((object)normal) : ((object)binding.bump)));
				if (progress > 0f || binding.normalKeyword)
				{
					binding.material.EnableKeyword("_NORMALMAP");
				}
				else
				{
					binding.material.DisableKeyword("_NORMALMAP");
				}
			}
		}
		for (int i = 0; i < weights.Length; i++)
		{
			weights[i] = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((progress - spread[i]) * 3f + progress * 0.25f));
		}
		foreach (Layer layer in layers)
		{
			for (int j = 0; j < flesh.Length; j++)
			{
				float num = weights[j];
				Color32 val = layer.original[j];
				Color32 val2 = flesh[j];
				ref Color32 reference = ref layer.frame[j];
				reference = (layer.overlay ? new Color32(val2.r, val2.g, val2.b, (byte)(num * 255f)) : new Color32((byte)((float)(int)val.r + (float)(val2.r - val.r) * num), (byte)((float)(int)val.g + (float)(val2.g - val.g) * num), (byte)((float)(int)val.b + (float)(val2.b - val.b) * num), val.a));
			}
			Write(layer.texture, layer.frame);
		}
		for (int k = 0; k < normalFull.Length; k++)
		{
			Color32 val3 = normalFull[k];
			ref Color32 reference2 = ref normalFrame[k];
			reference2 = new Color32(byte.MaxValue, (byte)(128f + (float)(val3.g - 128) * progress), (byte)(255f + (float)(val3.b - 255) * progress), (byte)(128f + (float)(val3.a - 128) * progress));
		}
		Write(normal, normalFrame);
	}

	private static void Write(Texture2D texture, Color32[] pixels)
	{
		typeof(Texture2D).GetMethod("SetPixels32", new Type[1] { typeof(Color32[]) }).Invoke(texture, new object[1] { pixels });
		texture.Apply(true, false);
	}

	internal void Restore()
	{
		bindings.Clear();
		foreach (Layer layer in layers)
		{
			if (Object.op_Implicit((Object)(object)layer.texture))
			{
				Object.Destroy((Object)(object)layer.texture);
			}
		}
		layers.Clear();
		cache.Clear();
		blank = null;
		if (Object.op_Implicit((Object)(object)normal))
		{
			Object.Destroy((Object)(object)normal);
		}
		normal = null;
	}
}
internal sealed class GateEncounter
{
	private ConfigEntry<bool> enabled;

	private ConfigEntry<float> escapeChance;

	private ConfigEntry<float> triggerDistance;

	private ConfigEntry<Vector3> position;

	private ConfigEntry<Vector3> facing;

	private ConfigEntry<KeyCode> markKey;

	private ConfigFile config;

	private ManualLogSource log;

	private GameObject actor;

	private GameObject native;

	private GameObject spawnAnchor;

	private NativeGateActor staged;

	private AudioSource voice;

	private AudioClip scream;

	private float nextScream;

	private float nextProbe;

	private float quietUntil;

	private double encounterStarted;

	private double encounterUntil;

	private bool attempted;

	private bool plannedEscape;

	private bool escaped;

	private bool escapeAttempted;

	private Vector3 eventPosition;

	private Vector3 eventFacing;

	private Renderer gate;

	private bool gateVisible;

	private Collider[] gateColliders;

	private bool[] gateColliderStates;

	internal void Initialize(ConfigFile c, ManualLogSource logger)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		config = c;
		log = logger;
		enabled = c.Bind<bool>("AirportGate", "Enabled", true, "The native stalker is always staged behind the gate; proximity can trigger breakout.");
		escapeChance = c.Bind<float>("AirportGate", "EscapeChance", 0.5f, new ConfigDescription("Host roll per approach encounter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		triggerDistance = c.Bind<float>("AirportGate", "TriggerDistance", 12f, new ConfigDescription("Any living airport player within this distance of the gate can trigger it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 25f), new object[0]));
		position = c.Bind<Vector3>("AirportGate", "Position", Vector3.zero, "Optional stalker feet position; F10 sets it behind the gate.");
		facing = c.Bind<Vector3>("AirportGate", "Facing", Vector3.forward, "Direction the trapped stalker faces.");
		markKey = c.Bind<KeyCode>("AirportGate", "PlacementKey", (KeyCode)291, "Aim at the gate and press F10 to calibrate.");
	}

	internal bool CheckPlacement()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//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_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//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_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: 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_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		if (!Input.GetKeyDown(markKey.Value) || !Object.op_Implicit((Object)(object)Camera.main))
		{
			return false;
		}
		Camera main = Camera.main;
		RaycastHit val = default(RaycastHit);
		if (!Physics.Raycast(((Component)main).transform.position, ((Component)main).transform.forward, ref val, 18f))
		{
			log.LogWarning((object)("Gate placement: aim at the gate within 18m and press " + markKey.Value));
			return false;
		}
		Vector3 val2 = ((RaycastHit)(ref val)).point - ((Component)main).transform.position;
		val2.y = 0f;
		if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
		{
			return false;
		}
		((Vector3)(ref val2)).Normalize();
		Vector3 val3 = ((RaycastHit)(ref val)).point + val2 * 1.1f;
		RaycastHit val4 = default(RaycastHit);
		if (Physics.Raycast(val3 + Vector3.up * 4f, Vector3.down, ref val4, 15f) && ((RaycastHit)(ref val4)).normal.y > 0.6f)
		{
			val3.y = ((RaycastHit)(ref val4)).point.y;
		}
		else
		{
			val3.y = ((Component)Character.localCharacter).transform.position.y;
		}
		Restore();
		gate = ((Component)((RaycastHit)(ref val)).collider).GetComponent<Renderer>();
		position.Value = val3;
		facing.Value = -val2;
		config.Save();
		DestroyActor();
		attempted = false;
		log.LogInfo((object)("Gate stalker location saved behind aimed gate: " + val3));
		return true;
	}

	internal bool Roll()
	{
		return Random.value < escapeChance.Value;
	}

	internal bool Placement(out Vector3 p, out Vector3 f)
	{
		//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_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0028: 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_0111: 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_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		p = position.Value;
		f = facing.Value;
		if (p != Vector3.zero)
		{
			if (!Object.op_Implicit((Object)(object)gate))
			{
				float num = float.MaxValue;
				MeshRenderer[] array = Object.FindObjectsByType<MeshRenderer>((FindObjectsSortMode)0);
				foreach (MeshRenderer val in array)
				{
					string text = ((Object)val).name.ToLowerInvariant();
					Bounds bounds = ((Renderer)val).bounds;
					Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(p) - p;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if ((text.Contains("gate") || text.Contains("fence")) && sqrMagnitude < num && sqrMagnitude < 20.25f)
					{
						Bounds bounds2 = ((Renderer)val).bounds;
						if (((Bounds)(ref bounds2)).size.y > 0.8f)
						{
							gate = (Renderer)(object)val;
							num = sqrMagnitude;
						}
					}
				}
			}
			if (Object.op_Implicit((Object)(object)gate))
			{
				Bounds bounds3 = gate.bounds;
				if (Vector3.Distance(((Bounds)(ref bounds3)).ClosestPoint(p), p) <= 4.5f)
				{
					return true;
				}
			}
			if (Locate(out p, out f))
			{
				log.LogWarning((object)("Saved gate position was away from a gate; using discovered basketball gate at " + p));
				return true;
			}
			return false;
		}
		return Locate(out p, out f);
	}

	internal void Begin(bool escape, Vector3 p, Vector3 f)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: 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)
		eventPosition = p;
		eventFacing = f;
	}

	internal void Update(float unused)
	{
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Expected O, but got Unknown
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Expected O, but got Unknown
		if (!enabled.Value || !PhotonNetwork.InRoom)
		{
			return;
		}
		if (!Object.op_Implicit((Object)(object)actor) && !escaped)
		{
			Scoutmaster[] array = Object.FindObjectsByType<Scoutmaster>((FindObjectsSortMode)0);
			foreach (Scoutmaster val in array)
			{
				if (NativeGateActor.Trapped(val))
				{
					PhotonView component = ((Component)val).GetComponent<PhotonView>();
					object[] instantiationData = component.InstantiationData;
					if (instantiationData.Length == 6 && instantiationData[1] is double && instantiationData[2] is double && instantiationData[3] is bool && !((double)instantiationData[2] <= PhotonNetwork.Time))
					{
						encounterStarted = (double)instantiationData[1];
						encounterUntil = (double)instantiationData[2];
						plannedEscape = (bool)instantiationData[3];
						Adopt(((Component)val).gameObject);
						attempted = true;
						break;
					}
				}
			}
		}
		if (!Object.op_Implicit((Object)(object)actor) && !attempted && PhotonNetwork.IsMasterClient && Time.unscaledTime >= quietUntil && Time.unscaledTime >= nextProbe)
		{
			nextProbe = Time.unscaledTime + 0.5f;
			if (Placement(out var p, out var f))
			{
				eventPosition = p;
				eventFacing = f;
				plannedEscape = false;
				escapeAttempted = false;
				encounterStarted = PhotonNetwork.Time;
				encounterUntil = encounterStarted + 36000.0;
				Room currentRoom = PhotonNetwork.CurrentRoom;
				Hashtable val2 = new Hashtable();
				((Dictionary<object, object>)(object)val2).Add((object)"peakStalker.gateBreak.v8.3", (object)0);
				((Dictionary<object, object>)(object)val2).Add((object)"peakStalker.gateAttempt.v8.3", (object)0);
				currentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
				attempted = true;
				Spawn();
			}
		}
		float num = (float)(PhotonNetwork.Time - encounterStarted);
		float num2 = (float)(encounterUntil - PhotonNetwork.Time);
		if (escaped && num2 <= 0f)
		{
			Restore();
			return;
		}
		if (!Object.op_Implicit((Object)(object)actor))
		{
			if (!escaped && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.gateBreak.v8.3", out object value) && value is int && (int)value > 0 && Object.op_Implicit((Object)(object)Plugin.Instance) && Object.op_Implicit((Object)(object)Plugin.Instance.AirportEnemy))
			{
				escaped = true;
				encounterUntil = PhotonNetwork.Time + 70.0;
				HideGate();
			}
			return;
		}
		if (num2 <= 0f)
		{
			Restore();
			return;
		}
		float num3 = Mathf.SmoothStep(0f, 1f, Mathf.Min(Mathf.Clamp01(num / 2f), Mathf.Clamp01(num2 / 2f)));
		if (Object.op_Implicit((Object)(object)staged) && Object.op_Implicit((Object)(object)staged.Visual))
		{
			staged.Visual.SetAirportFade(num3);
		}
		if (Object.op_Implicit((Object)(object)voice))
		{
			voice.volume = 0.55f * num3;
			if (num3 > 0.3f && !voice.isPlaying && Time.unscaledTime >= nextScream)
			{
				voice.PlayOneShot(scream);
				nextScream = Time.unscaledTime + scream.length + 3f;
			}
		}
		PhotonView component2 = actor.GetComponent<PhotonView>();
		if (Object.op_Implicit((Object)(object)component2) && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.gateAttempt.v8.3", out object value2) && value2 is int && (int)value2 == component2.ViewID)
		{
			escapeAttempted = true;
		}
		if (GateEscapePolicy.CanAttempt(PhotonNetwork.IsMasterClient, escapeAttempted, NearGate(actor.transform.position), num))
		{
			escapeAttempted = true;
			plannedEscape = Roll();
			Room currentRoom2 = PhotonNetwork.CurrentRoom;
			Hashtable val3 = new Hashtable();
			((Dictionary<object, object>)(object)val3).Add((object)"peakStalker.gateAttempt.v8.3", (object)component2.ViewID);
			((Dictionary<object, object>)(object)val3).Add((object)"peakStalker.gateBreak.v8.3", (object)(plannedEscape ? component2.ViewID : 0));
			currentRoom2.SetCustomProperties(val3, (Hashtable)null, (WebFlags)null);
		}
		object value3;
		bool flag = Object.op_Implicit((Object)(object)component2) && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"peakStalker.gateBreak.v8.3", out value3) && value3 is int && (int)value3 == component2.ViewID;
		if (!escaped && (flag || (PhotonNetwork.IsMasterClient && plannedEscape)))
		{
			BreakThrough();
		}
	}

	private bool NearGate(Vector3 p)
	{
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
		foreach (Character val in array)
		{
			if (Plugin.RigReady(val) && val.inAirport && !val.isBot && !val.isScoutmaster && !val.IsGhost && !val.gameOver && !val.data.dead)
			{
				Vector3 val2;
				if (!Object.op_Implicit((Object)(object)gate))
				{
					val2 = p;
				}
				else
				{
					Bounds bounds = gate.bounds;
					val2 = ((Bounds)(ref bounds)).ClosestPoint(val.Center);
				}
				Vector3 val3 = val2;
				if (Vector3.Distance(val.Center, val3) <= triggerDistance.Value)
				{
					return true;
				}
			}
		}
		return false;
	}

	private void Spawn()
	{
		//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_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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)
		Vector3 val = eventPosition;
		Vector3 forward = eventFacing;
		if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
		{
			forward = Vector3.forward;
		}
		spawnAnchor = new GameObject("PeakStalker_GateSpawnAnchor");
		spawnAnchor.transform.position = val;
		spawnAnchor.transform.rotation = Quaternion.LookRotation(forward, Vector3.up);
		try
		{
			GameObject val2 = PhotonNetwork.InstantiateRoomObject("Character_Scoutmaster", val, spawnAnchor.transform.rotation, (byte)0, new object[6]
			{
				"local.peak.stalker.trapped.v8.2",
				encounterStarted,
				encounterUntil,
				plannedEscape,
				val,
				spawnAnchor.transform.rotation
			});
			Character component = val2.GetComponent<Character>();
			if (Object.op_Implicit((Object)(object)component) && (Object)(object)component.data != (Object)null)
			{
				component.data.spawnPoint = spawnAnchor.transform;
			}
			Adopt(val2);
			log.LogInfo((object)("Native gate stalker staged continuously at " + val));
		}
		catch
		{
			Restore();
			throw;
		}
	}

	private void Adopt(GameObject instance)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		actor = instance;
		staged = actor.GetComponent<NativeGateActor>();
		if (!Object.op_Implicit((Object)(object)staged))
		{
			staged = actor.AddComponent<NativeGateActor>();
			staged.Initialize(log);
		}
		GameObject val = new GameObject("PeakStalker_GateVoice");
		val.transform.SetParent(actor.transform, false);
		val.transform.localPosition = new Vector3(0f, 2.2f, 0f);
		voice = val.AddComponent<AudioSource>();
		voice.playOnAwake = false;
		voice.spatialBlend = 1f;
		voice.rolloffMode = (AudioRolloffMode)1;
		voice.minDistance = 3f;
		voice.maxDistance = 50f;
		voice.dopplerLevel = 0f;
		voice.priority = 40;
		scream = HorrorAudio.Clip(HorrorAudio.Gate(), "Supplied trapped fence monster");
		nextScream = Time.unscaledTime + 1f;
	}

	private bool Locate(out Vector3 p, out Vector3 forward)
	{
		//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_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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: 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_0176: 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_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: 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_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: 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_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: 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_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: Unknown result type (might be due to invalid IL or missing references)
		//IL_0318: Unknown result type (might be due to invalid IL or missing references)
		p = Vector3.zero;
		forward = Vector3.forward;
		Transform val = null;
		float num = float.MaxValue;
		Vector3 center = Character.localCharacter.Center;
		Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsSortMode)0);
		foreach (Transform val2 in array)
		{
			string text = ((Object)val2).name.ToLowerInvariant();
			if (text.Contains("basket") || text.Contains("hoop") || text.Contains("court"))
			{
				Vector3 val3 = val2.position - center;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude < num && sqrMagnitude < 22500f)
				{
					num = sqrMagnitude;
					val = val2;
				}
			}
		}
		if (!Object.op_Implicit((Object)(object)val))
		{
			return false;
		}
		gate = null;
		num = float.MaxValue;
		MeshRenderer[] array2 = Object.FindObjectsByType<MeshRenderer>((FindObjectsSortMode)0);
		foreach (MeshRenderer val4 in array2)
		{
			string text2 = ((Object)val4).name.ToLowerInvariant();
			if (text2.Contains("gate") || text2.Contains("fence") || text2.Contains("barrier"))
			{
				Bounds bounds = ((Renderer)val4).bounds;
				Vector3 val5 = ((Bounds)(ref bounds)).center - val.position;
				float sqrMagnitude2 = ((Vector3)(ref val5)).sqrMagnitude;
				if (sqrMagnitude2 < num && sqrMagnitude2 < 484f)
				{
					gate = (Renderer)(object)val4;
					num = sqrMagnitude2;
				}
			}
		}
		if (!Object.op_Implicit((Object)(object)gate))
		{
			return false;
		}
		Bounds bounds2 = gate.bounds;
		Vector3 val6 = ((Bounds)(ref bounds2)).center - val.position;
		val6.y = 0f;
		if (((Vector3)(ref val6)).sqrMagnitude < 0.01f)
		{
			return false;
		}
		Bounds bounds3 = gate.bounds;
		float x = ((Bounds)(ref bounds3)).size.x;
		Bounds bounds4 = gate.bounds;
		val6 = ((x < ((Bounds)(ref bounds4)).size.z) ? (Vector3.right * Mathf.Sign(val6.x)) : (Vector3.forward * Mathf.Sign(val6.z)));
		if (((Vector3)(ref val6)).sqrMagnitude < 0.01f)
		{
			val6 = Vector3.forward;
		}
		float num2 = Mathf.Abs(val6.x);
		Bounds bounds5 = gate.bounds;
		float num3 = num2 * ((Bounds)(ref bounds5)).size.x;
		float num4 = Mathf.Abs(val6.z);
		Bounds bounds6 = gate.bounds;
		float num5 = (num3 + num4 * ((Bounds)(ref bounds6)).size.z) * 0.5f;
		Bounds bounds7 = gate.bounds;
		p = ((Bounds)(ref bounds7)).center + val6 * (num5 + 1.1f);
		Bounds bounds8 = gate.bounds;
		p.y = ((Bounds)(ref bounds8)).min.y;
		forward = -val6;
		RaycastHit val7 = default(RaycastHit);
		if (Physics.Raycast(p + Vector3.up * 4f, Vector3.down, ref val7, 15f) && ((RaycastHit)(ref val7)).normal.y > 0.6f)
		{
			p.y = ((RaycastHit)(ref val7)).point.y;
		}
		return true;
	}

	private void BreakThrough()
	{
		//IL_0019: 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_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)actor))
		{
			return;
		}
		Vector3 val = actor.transform.position + actor.transform.forward * 2.5f;
		Quaternion rotation = actor.transform.rotation;
		escaped = true;
		encounterUntil = PhotonNetwork.Time + 70.0;
		HideGate();
		DestroyActor();
		if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient)
		{
			return;
		}
		native = PhotonNetwork.InstantiateRoomObject("Character_Scoutmaster", val, rotation, (byte)0, new object[1] { "local.peak.stalker.airport" });
		Character component = native.GetComponent<Character>();
		if (Object.op_Implicit((Object)(object)spawnAnchor))
		{
			spawnAnchor.transform.position = val;
			if (Object.op_Implicit((Object)(object)component) && (Object)(object)component.data != (Object)null)
			{
				component.data.spawnPoint = spawnAnchor.transform;
			}
		}
		Scoutmaster component2 = native.GetComponent<Scoutmaster>();
		if (!Object.op_Implicit((Object)(object)component2))
		{
			throw new InvalidOperationException("Airport Scoutmaster controller missing");
		}
		if (Object.op_Implicit((Object)(object)Plugin.Instance))
		{
			Plugin.Instance.BeginAirportPursuit(component2);
		}
		log.LogInfo((object)"Gate stalker broke through and began native airport pursuit.");
	}

	private void HideGate()
	{
		if (!Object.op_Implicit((Object)(object)gate))
		{
			Placement(out var _, out var _);
		}
		if (Object.op_Implicit((Object)(object)gate))
		{
			gateVisible = gate.enabled;
			gate.enabled = false;
			gateColliders = ((Component)gate).GetComponents<Collider>();
			gateColliderStates = new bool[gateColliders.Length];
			for (int i = 0; i < gateColliders.Length; i++)
			{
				gateColliderStates[i] = gateColliders[i].enabled;
				gateColliders[i].enabled = false;
			}
		}
	}

	internal void Restore()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
		{
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)(object)val).Add((object)"peakStalker.gateBreak.v8.3", (object)0);
			((Dictionary<object, object>)(object)val).Add((object)"peakStalker.gateAttempt.v8.3", (object)0);
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
		DestroyActor();
		attempted = false;
		escaped = false;
		escapeAttempted = false;
		quietUntil = Time.unscaledTime + 5f;
		if (Object.op_Implicit((Object)(object)gate) && gateColliderStates != null)
		{
			gate.enabled = gateVisible;
		}
		if (gateColliders != null)
		{
			for (int i = 0; i < gateColliders.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)gateColliders[i]))
				{
					gateColliders[i].enabled = gateColliderStates[i];
				}
			}
		}
		gateColliders = null;
		gateColliderStates = null;
		if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
		{
			GameObject gameObject = native;
			if (!Object.op_Implicit((Object)(object)gameObject) && Object.op_Implicit((Object)(object)Plugin.Instance) && Object.op_Implicit((Object)(object)Plugin.Instance.AirportEnemy))
			{
				gameObject = ((Component)Plugin.Instance.AirportEnemy).gameObject;
			}
			if (Object.op_Implicit((Object)(object)gameObject))
			{
				PhotonNetwork.Destroy(gameObject);
			}
		}
		if (Object.op_Implicit((Object)(object)Plugin.Instance))
		{
			Plugin.Instance.EndAirportPursuit();
		}
		native = null;
		if (Object.op_Implicit((Object)(object)spawnAnchor))
		{
			Object.Destroy((Object)(object)spawnAnchor);
		}
		spawnAnchor = null;
	}

	private void DestroyActor()
	{
		if (Object.op_Implicit((Object)(object)voice))
		{
			AudioRetire.Fade(((Component)voice).gameObject, 2.5f, (AudioClip[])(object)new AudioClip[1] { scream });
		}
		else if (Object.op_Implicit((Object)(object)scream))
		{
			Object.Destroy((Object)(object)scream);
		}
		if (Object.op_Implicit((Object)(object)actor) && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
		{
			PhotonNetwork.Destroy(actor);
		}
		actor = null;
		staged = null;
		voice = null;
		scream = null;
	}
}
internal static class GateEscapePolicy
{
	internal static bool CanAttempt(bool host, bool attempted, bool nearby, float age)
	{
		if (host && !attempted && nearby)
		{
			return age >= 8f;
		}
		return false;
	}
}
public sealed class HauntedEffects : MonoBehaviour, IOnEventCallback
{
	private const byte RushEvent = 192;

	private const string RushTag = "local.peak.stalker.rush.v1";

	private const byte RampageEvent = 189;

	private const string RampageTag = "local.peak.stalker.rampage.v6";

	private const byte EventCode = 191;

	private const string Tag = "local.peak.stalker.v4";

	private bool pendingRush;

	private AudioSource rage;

	private AudioClip rageClip;

	private float rageUntil = -100f;

	private float rageStarted = -100f;

	private int pendingRageView;

	private double pendingRageEnd;

	private ConfigEntry<float> rageVolume;

	private ConfigEntry<bool> heartbeat;

	private ConfigEntry<bool> vignette;

	private ConfigEntry<float> volume;

	private ConfigEntry<float> cueVolume;

	private ConfigEntry<float> screamVolume;

	private ConfigEntry<float> fadeSeconds;

	private AudioSource heart;

	private AudioSource sting;

	private AudioSource throat;

	private GameObject throatObject;

	private AudioClip scream;

	private float audioGain;

	private float nextScream;

	private AudioClip beat;

	private AudioClip cue;

	private Scoutmaster enemy;

	private Character body;

	private int pendingView;

	private float spawnAt = -100f;

	private float strength;

	private bool announced;

	private bool broken;

	private bool loggedHeartbeat;

	private Material staticMaterial;

	private float oldStrength;

	private float oldGrain;

	private int currentStrengthId;

	private int currentGrainId;

	private static readonly FieldInfo Mat = typeof(Scoutmaster).GetField("mat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo StrengthId = typeof(Scoutmaster).GetField("STRENGTHID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo GrainId = typeof(Scoutmaster).GetField("GRAINMULTID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	public void Initialize(ConfigFile config)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Expected O, but got Unknown
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Expected O, but got Unknown
		heartbeat = config.Bind<bool>("Audio", "HeartbeatEnabled", true, "Supplied heartbeat ambience grows louder within 50 metres, retaining its recorded pace.");
		volume = config.Bind<float>("Audio", "HeartbeatVolume", 0.55f, new ConfigDescription("Maximum heartbeat loudness.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		cueVolume = config.Bind<float>("Audio", "SpawnCueVolume", 0.45f, new ConfigDescription("Haunted arrival sound loudness; zero disables it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		fadeSeconds = config.Bind<float>("Audio", "FadeSeconds", 2.5f, new ConfigDescription("Fade time for proximity and scene changes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), new object[0]));
		screamVolume = config.Bind<float>("Audio", "StalkerScreamVolume", 0.55f, new ConfigDescription("Occasional directional screams from the pursuing stalker.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		vignette = config.Bind<bool>("VisualFX", "SpawnVignette", true, "Brief slow darkening at arrival. Suppressed when photosensitivity is enabled.");
		rageVolume = config.Bind<float>("Audio", "RampageScreamVolume", 0.45f, new ConfigDescription("Dedicated rampage scream, audible up to 110 metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		ConfigEntry<bool> val = config.Bind<bool>("Audio", "V7VolumeApplied", false, "Internal marker for the one-time v7 rampage volume reduction.");
		if (!val.Value)
		{
			rageVolume.Value = Mathf.Min(rageVolume.Value, 0.45f);
			val.Value = true;
			config.Save();
		}
		beat = Sound(arrival: false);
		cue = Sound(arrival: true);
		heart = ((Component)this).gameObject.AddComponent<AudioSource>();
		sting = ((Component)this).gameObject.AddComponent<AudioSource>();
		Configure(heart);
		Configure(sting);
		heart.clip = beat;
		heart.loop = true;
		heart.volume = 0f;
		scream = HorrorAudio.Clip(HorrorAudio.Scream(), "Supplied monster recording");
		throatObject = new GameObject("PeakStalker_DirectionalScream");
		throatObject.transform.SetParent(((Component)this).transform, false);
		throat = throatObject.AddComponent<AudioSource>();
		Configure(throat);
		throat.spatialBlend = 1f;
		throat.rolloffMode = (AudioRolloffMode)1;
		throat.minDistance = 3f;
		throat.maxDistance = 65f;
		throat.volume = 0f;
		rageClip = HorrorAudio.Clip(HorrorAudio.Rampage(), "Supplied rampage scream");
		rage = throatObject.AddComponent<AudioSource>();
		Configure(rage);
		rage.spatialBlend = 1f;
		rage.rolloffMode = (AudioRolloffMode)1;
		rage.minDistance = 8f;
		rage.maxDistance = 110f;
		rage.volume = 0f;
		rage.clip = rageClip;
		Debug.Log((object)("Peak Stalker 1.0.2 supplied audio ready: heartbeat=" + heartbeat.Value + ", heartbeat volume=" + volume.Value + ", arrival volume=" + cueVolume.Value + ", rampage volume=" + rageVolume.Value));
		PhotonNetwork.AddCallbackTarget((object)this);
	}

	private static void Configure(AudioSource source)
	{
		source.playOnAwake = false;
		source.loop = false;
		source.spatialBlend = 0f;
		source.dopplerLevel = 0f;
		source.priority = 32;
		source.volume = 1f;
	}

	public void BroadcastSpawn(Scoutmaster scout)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		PhotonView component = ((Component)scout).GetComponent<PhotonView>();
		if (Object.op_Implicit((Object)(object)component))
		{
			Activate(scout, arrival: true);
			object[] obj = new object[2] { "local.peak.stalker.v4", component.ViewID };
			RaiseEventOptions val = new RaiseEventOptions();
			val.Receivers = (ReceiverGroup)0;
			PhotonNetwork.RaiseEvent((byte)191, (object)obj, val, SendOptions.SendReliable);
		}
	}

	public void BroadcastRampage(Scoutmaster scout, float duration)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		//IL_0054: 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)
		PhotonView component = ((Component)scout).GetComponent<PhotonView>();
		if (Object.op_Implicit((Object)(object)component))
		{
			PlayRampage(scout, duration);
			object[] obj = new object[3]
			{
				"local.peak.stalker.rampage.v6",
				component.ViewID,
				PhotonNetwork.Time + (double)duration
			};
			RaiseEventOptions val = new RaiseEventOptions();
			val.Receivers = (ReceiverGroup)0;
			PhotonNetwork.RaiseEvent((byte)189, (object)obj, val, SendOptions.SendReliable);
		}
	}

	public void BroadcastRush(Scoutmaster scout)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		PhotonView component = ((Component)scout).GetComponent<PhotonView>();
		if (Object.op_Implicit((Object)(object)component))
		{
			float num = Mathf.Min(rageClip.length, 30f);
			PlayRampage(scout, num, rush: true);
			object[] obj = new object[3]
			{
				"local.peak.stalker.rush.v1",
				component.ViewID,
				PhotonNetwork.Time + (double)num
			};
			RaiseEventOptions val = new RaiseEventOptions();
			val.Receivers = (ReceiverGroup)0;
			PhotonNetwork.RaiseEvent((byte)192, (object)obj, val, SendOptions.SendReliable);
		}
	}

	private void PlayRampage(Scoutmaster scout, float duration, bool rush = false)
	{
		if (!(duration <= 0f))
		{
			Activate(scout, arrival: false);
			rageStarted = Time.time;
			rageUntil = Time.time + duration;
			rage.volume = 0f;
			rage.maxDistance = (rush ? 600 : 110);
			rage.Play();
			nextScream = Time.time + duration + 8f;
		}
	}

	private void UpdateRage(bool active)
	{
		if (Object.op_Implicit((Object)(object)rage))
		{
			float time = Time.time;
			float num = ((active && time < rageUntil) ? (rageVolume.Value * Mathf.Clamp01((time - rageStarted) / 0.3f) * Mathf.Clamp01((rageUntil - time) / fadeSeconds.Value)) : 0f);
			rage.volume = Mathf.MoveTowards(rage.volume, num, Time.unscaledDeltaTime / fadeSeconds.Value);
			if (rage.volume < 0.001f && (!active || time >= rageUntil))
			{
				rage.Stop();
			}
		}
	}

	public void OnEvent(EventData e)
	{
		if (e.Code == 189 || e.Code == 192)
		{
			if (e.CustomData is object[] array && array.Length == 3 && array[0] is string && !((string)array[0] != ((e.Code == 192) ? "local.peak.stalker.rush.v1" : "local.peak.stalker.rampage.v6")) && array[1] is int && array[2] is double && PhotonNetwork.CurrentRoom != null && e.Sender == PhotonNetwork.CurrentRoom.MasterClientId)
			{
				pendingRush = e.Code == 192;
				pendingRageView = (int)array[1];
				pendingRageEnd = (double)array[2];
			}
		}
		else if (e.Code == 191 && e.CustomData is object[] array2 && array2.Length == 2 && array2[0] is string && !((string)array2[0] != "local.peak.stalker.v4") && array2[1] is int && PhotonNetwork.CurrentRoom != null && e.Sender == PhotonNetwork.CurrentRoom.MasterClientId)
		{
			pendingView = (int)array2[1];
		}
	}

	private void Activate(Scoutmaster scout, bool arrival)
	{
		enemy = scout;
		body = ((Component)scout).GetComponent<Character>();
		if (!Object.op_Implicit((Object)(object)body))
		{
			return;
		}
		object? value = Mat.GetValue(scout);
		Material val = (Material)((value is Material) ? value : null);
		if ((Object)(object)val != (Object)(object)staticMaterial)
		{
			RestoreStatic();
			staticMaterial = val;
			if (Object.op_Implicit((Object)(object)val))
			{
				currentStrengthId = (int)StrengthId.GetValue(scout);
				currentGrainId = (int)GrainId.GetValue(scout);
				oldStrength = val.GetFloat(currentStrengthId);
				oldGrain = val.GetFloat(currentGrainId);
			}
		}
		if (arrival && !announced)
		{
			announced = true;
			spawnAt = Time.time;
			sting.volume = 1f;
			sting.PlayOneShot(cue, cueVolume.Value);
			nextScream = Time.time + cue.length + 2f;
			Debug.Log((object)("Peak Stalker arrival cue played; volume=" + cueVolume.Value));
		}
	}

	private bool Photosensitive()
	{
		if (Object.op_Implicit((Object)(object)GUIManager.instance))
		{
			return GUIManager.instance.photosensitivity;
		}
		return false;
	}

	private void LateUpdate()
	{
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		if (broken)
		{
			FadeAudio();
			return;
		}
		try
		{
			Character localCharacter = Character.localCharacter;
			if (!PhotonNetwork.InRoom || !Object.op_Implicit((Object)(object)localCharacter) || (!localCharacter.inAirport && !HauntedSession.Unlocked) || (localCharacter.inAirport && (!Object.op_Implicit((Object)(object)Plugin.Instance) || !Object.op_Implicit((Object)(object)Plugin.Instance.AirportEnemy))) || localCharacter.gameOver)
			{
				ResetRun();
				return;
			}
			if (pendingRageView != 0)
			{
				float num = (float)(pendingRageEnd - PhotonNetwork.Time);
				if (num <= 0f)
				{
					pendingRageView = 0;
				}
				else
				{
					PhotonView val = PhotonView.Find(pendingRageView);
					if (Object.op_Implicit((Object)(object)val))
					{
						Scoutmaster component = ((Component)val).GetComponent<Scoutmaster>();
						if (Object.op_Implicit((Object)(object)component))
						{
							PlayRampage(component, Mathf.Min(num, 30f), pendingRush);
							pendingRageView = 0;
						}
					}
				}
			}
			if (pendingView != 0)
			{
				PhotonView val2 = PhotonView.Find(pendingView);
				if (Object.op_Implicit((Object)(object)val2))
				{
					Scoutmaster component2 = ((Component)val2).GetComponent<Scoutmaster>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						Activate(component2, arrival: true);
						pendingView = 0;
					}
				}
			}
			Scoutmaster airportEnemy = default(Scoutmaster);
			if (!Object.op_Implicit((Object)(object)enemy) && !PhotonNetwork.IsMasterClient && ((localCharacter.inAirport && Object.op_Implicit((Object)(object)Plugin.Instance) && Object.op_Implicit((Object)(object)Plugin.Instance.AirportEnemy)) ? ((Object)(object)(airportEnemy = Plugin.Instance.AirportEnemy) != (Object)null) : Scoutmaster.GetPrimaryScoutmaster(ref airportEnemy)) && Object.op_Implicit((Object)(object)airportEnemy) && Object.op_Implicit((Object)(object)airportEnemy.currentTarget))
			{
				Character component3 = ((Component)airportEnemy).GetComponent<Character>();
				if (Object.op_Implicit((Object)(object)component3) && component3.refs != null && Object.op_Implicit((Object)(object)component3.refs.ragdoll) && component3.refs.ragdoll.partDict.ContainsKey((BodypartType)2) && Vector3.Distance(component3.Center, localCharacter.Center) < 90f)