Decompiled source of Hanging Angel v1.0.0

AngelColgante.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Trepidrock")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Trepidrock")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AngelColgante")]
[assembly: AssemblyTitle("AngelColgante")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AngelColgante
{
	internal static class AngelAssets
	{
		internal class Part
		{
			internal int Parent;

			internal Vector3 Pivot;

			internal Mesh Mesh;
		}

		internal const float RingY = 1.067f;

		internal const float WingTopY = 0.535f;

		internal const float ModelHeight = 1.085f;

		internal static readonly List<Part> Parts = new List<Part>();

		internal static Mesh CrossMesh;

		internal static Mesh TorusMesh;

		internal static Mesh BeamMesh;

		private static Material body;

		private static Material cross;

		private static Material thread;

		private static Material halo;

		private static Material beam;

		private static bool ready;

		internal static Material Body
		{
			get
			{
				EnsureMaterials();
				return body;
			}
		}

		internal static Material Cross
		{
			get
			{
				EnsureMaterials();
				return cross;
			}
		}

		internal static Material Thread
		{
			get
			{
				EnsureMaterials();
				return thread;
			}
		}

		internal static Material Halo
		{
			get
			{
				EnsureMaterials();
				return halo;
			}
		}

		internal static Material Beam
		{
			get
			{
				EnsureMaterials();
				return beam;
			}
		}

		internal static void Init()
		{
			LoadParts("Alas.tsp");
			CrossMesh = LoadMesh("Cruceta.tsm");
			TorusMesh = LoadMesh("Halo.tsm") ?? MakeTorus(1f, 0.08f, 32, 8);
			BeamMesh = MakeTube(1f, 1f, 24);
		}

		private static void EnsureMaterials()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			if (!ready)
			{
				ready = true;
				Texture2D val = LoadTexture("Angel_BaseColor.png", linear: false);
				Texture2D val2 = LoadTexture("Angel_Emissive.png", linear: false);
				body = NewLit("AngelBody");
				body.SetTexture("_BaseColorMap", (Texture)(object)val);
				body.SetFloat("_Smoothness", 0.25f);
				body.SetTexture("_EmissiveColorMap", (Texture)(object)val2);
				body.EnableKeyword("_EMISSIVE_COLOR_MAP");
				body.SetFloat("_UseEmissiveIntensity", 0f);
				body.SetColor("_EmissiveColor", Color.white * 2.2f);
				body.SetFloat("_EmissiveExposureWeight", 0f);
				body.SetFloat("_DoubleSidedEnable", 1f);
				body.SetFloat("_CullMode", 0f);
				body.SetFloat("_CullModeForward", 0f);
				Validate(body);
				cross = NewLit("AngelCruceta");
				cross.SetTexture("_BaseColorMap", (Texture)(object)val);
				MakeTransparent(cross, "_BaseColor", new Color(1f, 1f, 1f, Mathf.Clamp01(Plugin.CrossbarOpacity.Value)));
				Validate(cross);
				float num = Mathf.Clamp01(Plugin.ThreadVisibility.Value);
				thread = NewUnlit("AngelHilo");
				MakeTransparent(thread, "_UnlitColor", new Color(0.86f, 0.86f, 0.9f, 0.25f + 0.75f * num));
				Validate(thread);
				halo = NewUnlit("AngelHalo");
				halo.SetColor("_UnlitColor", new Color(1f, 0.82f, 0.38f, 1f) * (1.6f * Mathf.Max(0.05f, Plugin.HaloGlow.Value)));
				Validate(halo);
				beam = NewUnlit("AngelHaz");
				MakeTransparent(beam, "_UnlitColor", new Color(1f, 0.93f, 0.75f, 0.22f));
				beam.SetFloat("_DoubleSidedEnable", 1f);
				beam.SetFloat("_CullMode", 0f);
				beam.SetFloat("_CullModeForward", 0f);
				Validate(beam);
			}
		}

		private static Material NewLit(string name)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0027: Expected O, but got Unknown
			Material val = new Material(Shader.Find("HDRP/Lit"))
			{
				name = name
			};
			val.SetColor("_BaseColor", Color.white);
			return val;
		}

		private static Material NewUnlit(string name)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			Shader val = Shader.Find("HDRP/Unlit");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[AngelColgante] HDRP/Unlit no encontrado, uso HDRP/Lit");
				val = Shader.Find("HDRP/Lit");
			}
			return new Material(val)
			{
				name = name
			};
		}

		private static void MakeTransparent(Material m, string colorProp, Color c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			m.SetColor(colorProp, c);
			m.SetFloat("_SurfaceType", 1f);
			m.SetFloat("_BlendMode", 0f);
			m.SetFloat("_ZWrite", 0f);
			m.SetFloat("_TransparentZWrite", 0f);
			m.SetFloat("_EnableFogOnTransparent", 1f);
			m.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			m.EnableKeyword("_BLENDMODE_ALPHA");
			m.renderQueue = 3000;
		}

		private static void Validate(Material m)
		{
			try
			{
				HDMaterial.ValidateMaterial(m);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[AngelColgante] ValidateMaterial fallo en " + ((Object)m).name + ": " + ex.Message));
			}
		}

		private static Mesh LoadMesh(string file)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			string text = Plugin.FindFile(file);
			if (text == null)
			{
				return null;
			}
			using BinaryReader binaryReader = new BinaryReader(File.OpenRead(text));
			if (new string(binaryReader.ReadChars(4)) != "TSM1")
			{
				Plugin.Log.LogError((object)("[AngelColgante] " + file + " no es un modelo valido"));
				return null;
			}
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector2[] array3 = (Vector2[])(object)new Vector2[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array2[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				array3[i] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
			}
			int[] array4 = new int[num2];
			for (int j = 0; j < num2; j++)
			{
				array4[j] = binaryReader.ReadInt32();
			}
			Mesh val = new Mesh
			{
				name = Path.GetFileNameWithoutExtension(file)
			};
			if (num > 65000)
			{
				val.indexFormat = (IndexFormat)1;
			}
			val.vertices = array;
			val.normals = array2;
			val.uv = array3;
			val.triangles = array4;
			val.RecalculateBounds();
			val.RecalculateTangents();
			Plugin.Log.LogInfo((object)$"[AngelColgante] Modelo {file}: {num} vertices, {num2 / 3} triangulos");
			return val;
		}

		private static void LoadParts(string file)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f6: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			string text = Plugin.FindFile(file);
			if (text == null)
			{
				return;
			}
			using BinaryReader binaryReader = new BinaryReader(File.OpenRead(text));
			if (new string(binaryReader.ReadChars(4)) != "TSP1")
			{
				Plugin.Log.LogError((object)("[AngelColgante] " + file + " no es valido"));
				return;
			}
			int num = binaryReader.ReadInt32();
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				Part part = new Part
				{
					Parent = binaryReader.ReadInt32(),
					Pivot = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())
				};
				int num3 = binaryReader.ReadInt32();
				int num4 = binaryReader.ReadInt32();
				Vector3[] array = (Vector3[])(object)new Vector3[num3];
				Vector3[] array2 = (Vector3[])(object)new Vector3[num3];
				Vector2[] array3 = (Vector2[])(object)new Vector2[num3];
				for (int j = 0; j < num3; j++)
				{
					array[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					array3[j] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
				}
				int[] array4 = new int[num4];
				for (int k = 0; k < num4; k++)
				{
					array4[k] = binaryReader.ReadInt32();
				}
				Mesh val = new Mesh
				{
					name = "AngelPieza" + i
				};
				val.vertices = array;
				val.normals = array2;
				val.uv = array3;
				val.triangles = array4;
				val.RecalculateBounds();
				part.Mesh = val;
				Parts.Add(part);
				num2 += num4 / 3;
			}
			Plugin.Log.LogInfo((object)$"[AngelColgante] Cuerpo: {num} piezas ({(num - 1) / 2} alas), {num2} triangulos");
		}

		private static Texture2D LoadTexture(string file, bool linear)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = Path.GetFileNameWithoutExtension(file)
			};
			string text = Plugin.FindFile(file);
			if (text != null)
			{
				ImageConversion.LoadImage(val, File.ReadAllBytes(text));
			}
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)0;
			val.Apply(false, true);
			return val;
		}

		private static Mesh MakeTorus(float R, float r, int segR, int segr)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00a3: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: 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_018e: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[segR * segr];
			Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length];
			int[] array3 = new int[segR * segr * 6];
			Vector3 val = default(Vector3);
			for (int i = 0; i < segR; i++)
			{
				float num = MathF.PI * 2f * (float)i / (float)segR;
				((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
				for (int j = 0; j < segr; j++)
				{
					float num2 = MathF.PI * 2f * (float)j / (float)segr;
					Vector3 val2 = val * Mathf.Cos(num2) + Vector3.up * Mathf.Sin(num2);
					array[i * segr + j] = val * R + val2 * r;
					array2[i * segr + j] = val2;
				}
			}
			int num3 = 0;
			for (int k = 0; k < segR; k++)
			{
				for (int l = 0; l < segr; l++)
				{
					int num4 = k * segr + l;
					int num5 = (k + 1) % segR * segr + l;
					int num6 = (k + 1) % segR * segr + (l + 1) % segr;
					int num7 = k * segr + (l + 1) % segr;
					array3[num3++] = num4;
					array3[num3++] = num7;
					array3[num3++] = num5;
					array3[num3++] = num5;
					array3[num3++] = num7;
					array3[num3++] = num6;
				}
			}
			Mesh val3 = new Mesh
			{
				name = "AngelHalo",
				vertices = array,
				normals = array2,
				triangles = array3
			};
			val3.RecalculateBounds();
			return val3;
		}

		private static Mesh MakeTube(float radius, float height, int seg)
		{
			//IL_004c: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[(seg + 1) * 2];
			Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length];
			int[] array3 = new int[seg * 6];
			Vector3 val = default(Vector3);
			for (int i = 0; i <= seg; i++)
			{
				float num = MathF.PI * 2f * (float)i / (float)seg;
				((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
				array[i * 2] = val * radius;
				array[i * 2 + 1] = val * radius + Vector3.up * height;
				array2[i * 2] = (array2[i * 2 + 1] = val);
			}
			int j = 0;
			int num2 = 0;
			for (; j < seg; j++)
			{
				int num3 = j * 2;
				array3[num2++] = num3;
				array3[num2++] = num3 + 1;
				array3[num2++] = num3 + 2;
				array3[num2++] = num3 + 2;
				array3[num2++] = num3 + 1;
				array3[num2++] = num3 + 3;
			}
			Mesh val2 = new Mesh
			{
				name = "AngelHaz",
				vertices = array,
				normals = array2,
				triangles = array3
			};
			val2.RecalculateBounds();
			return val2;
		}

		internal static LineRenderer NewLine(string name, Transform parent, float width)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			if ((Object)(object)parent != (Object)null)
			{
				val.transform.SetParent(parent, false);
			}
			LineRenderer obj = val.AddComponent<LineRenderer>();
			((Renderer)obj).sharedMaterial = Thread;
			obj.positionCount = 2;
			obj.useWorldSpace = true;
			obj.widthMultiplier = width;
			obj.numCapVertices = 0;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			obj.alignment = (LineAlignment)0;
			return obj;
		}

		internal static GameObject NewMeshObject(string name, Transform parent, Mesh mesh, Material mat, bool shadows)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			if ((Object)(object)parent != (Object)null)
			{
				val.transform.SetParent(parent, false);
			}
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = mat;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)(shadows ? 1 : 0);
			return val;
		}

		internal static Light NewLight(string name, Transform parent, HDLightTypeAndShape shape, Color c, float intensity, float range)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject(name);
				if ((Object)(object)parent != (Object)null)
				{
					val.transform.SetParent(parent, false);
				}
				HDAdditionalLightData val2 = GameObjectExtension.AddHDLight(val, shape);
				val2.SetColor(c, -1f);
				val2.SetIntensity(intensity);
				val2.SetRange(range);
				try
				{
					val2.EnableShadows(false);
				}
				catch
				{
				}
				Light component = val.GetComponent<Light>();
				if ((Object)(object)component != (Object)null)
				{
					component.shadows = (LightShadows)0;
				}
				return component;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[AngelColgante] No se pudo crear la luz " + name + ": " + ex.Message));
				return null;
			}
		}

		internal static AudioSource NewSource(GameObject go, float maxDistance)
		{
			AudioSource obj = go.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.spatialBlend = 1f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.minDistance = 4f;
			obj.maxDistance = maxDistance;
			obj.dopplerLevel = 0f;
			obj.volume = Mathf.Clamp01(Plugin.Volume.Value);
			return obj;
		}
	}
	internal class AngelDirector : MonoBehaviour
	{
		private class ThreadInfo
		{
			internal int Id;

			internal Vector3 Bottom;

			internal float TopY;

			internal LineRenderer Line;

			internal float TouchSent;

			internal float Born;
		}

		private class MarkInfo
		{
			internal float Expire;

			internal GameObject Halo;

			internal Light HaloLight;

			internal float HeadY = -1f;
		}

		internal class Carry
		{
			internal int Player;

			internal ulong AngelId;

			internal Vector3 Start;

			internal float Yaw;

			internal float T0;

			internal int Ties;

			internal bool[] Untied = new bool[3];

			internal LineRenderer[] Lines = (LineRenderer[])(object)new LineRenderer[3];

			internal float Elapsed => Time.time - T0;

			internal float AttachDuration => 0.3f + (float)Ties * 0.5f;

			internal float Lift => Mathf.Max(0f, Elapsed - AttachDuration) * Plugin.LiftSpeed.Value;

			internal int TiedCount(int k)
			{
				return (Elapsed >= 0.3f + (float)k * 0.5f) ? 1 : 0;
			}

			internal bool IsTied(int k)
			{
				if (k < Ties && !Untied[k])
				{
					return Elapsed >= 0.3f + (float)k * 0.5f;
				}
				return false;
			}
		}

		private class Hanged
		{
			internal DeadBodyInfo Body;

			internal Transform Anchor;

			internal Rigidbody Neck;

			internal LineRenderer Line;
		}

		internal static AngelDirector Instance;

		private static readonly Dictionary<int, ThreadInfo> threads = new Dictionary<int, ThreadInfo>();

		private static readonly Dictionary<int, MarkInfo> marks = new Dictionary<int, MarkInfo>();

		private static readonly Dictionary<int, Carry> carries = new Dictionary<int, Carry>();

		private static readonly Dictionary<int, float> serverMarks = new Dictionary<int, float>();

		private static readonly Dictionary<int, float> serverMarkCooldown = new Dictionary<int, float>();

		private static int nextThreadId = 1;

		private bool dayDecided;

		private bool spawnToday;

		private bool spawnedToday;

		private float spawnHour;

		private float landedTime;

		private int localHits;

		private readonly float[] untieProg = new float[3];

		private int untieTarget = -1;

		private float lastOnTarget;

		private bool fillShown;

		private float safeFallUntil;

		private bool wasCarried;

		private bool wasInShipPhase = true;

		private readonly List<(GameObject go, float t0, float dur, Light light, MeshRenderer mr)> beams = new List<(GameObject, float, float, Light, MeshRenderer)>();

		private MaterialPropertyBlock mpb;

		private static readonly Dictionary<int, float> dropped = new Dictionary<int, float>();

		private readonly List<Hanged> hanged = new List<Hanged>();

		internal static int ThreadCount => threads.Count;

		private static PlayerControllerB Local
		{
			get
			{
				if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
				{
					return null;
				}
				return GameNetworkManager.Instance.localPlayerController;
			}
		}

		internal static Carry GetCarry(int player)
		{
			if (player < 0 || !carries.TryGetValue(player, out var value))
			{
				return null;
			}
			return value;
		}

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Instance = this;
			mpb = new MaterialPropertyBlock();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			ClearAll();
		}

		private void Update()
		{
			StartOfRound instance = StartOfRound.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if (instance.inShipPhase && !wasInShipPhase)
				{
					ClearAll();
				}
				wasInShipPhase = instance.inShipPhase;
				if (AngelNet.IsServer)
				{
					ServerSpawner(instance);
					ServerMarks(instance);
					ServerExpireThreads();
				}
				LocalTouchCheck();
				CheckDroppedDeaths();
				UpdateBeams();
			}
		}

		private void LateUpdate()
		{
			LocalCarryMove();
			LocalUntie();
			DrawCarries();
			DrawHalos();
			DrawHanged();
		}

		internal static void ClearAll()
		{
			foreach (ThreadInfo value in threads.Values)
			{
				if ((Object)(object)value.Line != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value.Line).gameObject);
				}
			}
			threads.Clear();
			foreach (MarkInfo value2 in marks.Values)
			{
				if ((Object)(object)value2.Halo != (Object)null)
				{
					Object.Destroy((Object)(object)value2.Halo);
				}
			}
			marks.Clear();
			foreach (Carry value3 in carries.Values)
			{
				LineRenderer[] lines = value3.Lines;
				foreach (LineRenderer val in lines)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
			}
			carries.Clear();
			serverMarks.Clear();
			serverMarkCooldown.Clear();
			dropped.Clear();
			PlayerControllerB local = Local;
			if ((Object)(object)local != (Object)null)
			{
				local.disableMoveInput = false;
			}
			if (!((Object)(object)Instance != (Object)null))
			{
				return;
			}
			foreach (var beam in Instance.beams)
			{
				if ((Object)(object)beam.go != (Object)null)
				{
					Object.Destroy((Object)(object)beam.go);
				}
			}
			foreach (Hanged item in Instance.hanged)
			{
				if ((Object)(object)item.Line != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)item.Line).gameObject);
				}
				if ((Object)(object)item.Anchor != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)item.Anchor).gameObject);
				}
			}
			Instance.hanged.Clear();
			Instance.beams.Clear();
			Instance.wasCarried = false;
			Instance.localHits = 0;
			Instance.untieTarget = -1;
			Instance.dayDecided = false;
			Instance.spawnedToday = false;
		}

		private static float CurrentHour()
		{
			TimeOfDay instance = TimeOfDay.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return 0f;
			}
			return 6f + instance.normalizedTimeOfDay * (float)instance.numberOfHours;
		}

		private static bool MoonAllowed(SelectableLevel level)
		{
			string value = Plugin.Moons.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				return true;
			}
			string[] array = value.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0 && level.PlanetName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private void ServerSpawner(StartOfRound sor)
		{
			if (sor.inShipPhase || !sor.shipHasLanded)
			{
				landedTime = 0f;
				return;
			}
			if (landedTime == 0f)
			{
				landedTime = Time.time;
			}
			SelectableLevel currentLevel = sor.currentLevel;
			if (!((Object)(object)currentLevel == (Object)null) && currentLevel.planetHasTime && currentLevel.spawnEnemiesAndScrap)
			{
				if (!dayDecided)
				{
					dayDecided = true;
					spawnedToday = false;
					spawnToday = Plugin.TestMode.Value || (MoonAllowed(currentLevel) && Random.value < Mathf.Clamp01(Plugin.Chance.Value));
					spawnHour = (Plugin.TestMode.Value ? 0f : (Plugin.SpawnHour.Value + Random.Range(0f, Mathf.Max(0f, Plugin.SpawnWindow.Value))));
					Plugin.Log.LogInfo((object)string.Format("[AngelColgante] Luna {0}: {1} (hora actual {2:0.00}, horas del dia {3})", currentLevel.PlanetName, spawnToday ? $"aparecera a las {spawnHour:0.00} h" : "no aparece hoy", CurrentHour(), TimeOfDay.Instance?.numberOfHours));
				}
				if (spawnToday && !spawnedToday && !(CurrentHour() < spawnHour) && !(Time.time - landedTime < (Plugin.TestMode.Value ? 20f : 10f)))
				{
					spawnedToday = true;
					ServerSpawnAngel(sor);
				}
			}
		}

		internal static void ServerSpawnAngel(StartOfRound sor)
		{
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_014a: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)AngelEnemy.Type == (Object)null)
			{
				return;
			}
			Vector3 position = sor.elevatorTransform.position;
			Vector3 val = position + new Vector3(40f, 0f, 40f);
			GameObject[] outsideAINodes = instance.outsideAINodes;
			if (outsideAINodes != null && outsideAINodes.Length != 0)
			{
				List<GameObject> list = new List<GameObject>();
				GameObject[] array = outsideAINodes;
				foreach (GameObject val2 in array)
				{
					if ((Object)(object)val2 != (Object)null && Vector3.Distance(val2.transform.position, position) > 45f)
					{
						list.Add(val2);
					}
				}
				val = ((list.Count > 0) ? list[Random.Range(0, list.Count)] : outsideAINodes[Random.Range(0, outsideAINodes.Length)]).transform.position;
			}
			val.y = AngelEnemy.GroundAt(val, val.y + 50f);
			AngelNet.Broadcast(new AngelNet.Packet
			{
				Type = AngelNet.M.Beam,
				V = val,
				F = 16f
			});
			Vector3 val3 = val + Vector3.up * (Plugin.PatrolHeight.Value + AngelEnemy.RingDrop + 70f);
			instance.SpawnEnemyGameObject(val3, 0f, -1, AngelEnemy.Type);
			Plugin.Log.LogInfo((object)$"[AngelColgante] Haz de luz en {val}, angel creado en {val3}");
		}

		internal static void ServerAddThread(Vector3 bottom, float topY)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			AngelNet.Broadcast(new AngelNet.Packet
			{
				Type = AngelNet.M.ThreadAdd,
				A = nextThreadId++,
				V = bottom,
				F = topY
			});
		}

		private static void ServerExpireThreads()
		{
			float num = Mathf.Max(10f, Plugin.ThreadLife.Value);
			List<int> list = null;
			foreach (ThreadInfo value in threads.Values)
			{
				if (Time.time - value.Born > num)
				{
					(list ?? (list = new List<int>())).Add(value.Id);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				AngelNet.Broadcast(new AngelNet.Packet
				{
					Type = AngelNet.M.ThreadRemove,
					A = item,
					B = 2
				});
			}
		}

		internal static void OnThreadAdd(int id, Vector3 bottom, float topY)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!threads.ContainsKey(id) && !((Object)(object)Instance == (Object)null))
			{
				LineRenderer val = AngelAssets.NewLine("AngelHilo" + id, ((Component)Instance).transform, Plugin.ThreadWidth.Value);
				val.SetPosition(0, bottom);
				val.SetPosition(1, new Vector3(bottom.x, topY, bottom.z));
				threads[id] = new ThreadInfo
				{
					Id = id,
					Bottom = bottom,
					TopY = topY,
					Line = val,
					Born = Time.time
				};
			}
		}

		internal static void OnThreadRemove(int id, int reason)
		{
			if (threads.TryGetValue(id, out var value))
			{
				threads.Remove(id);
				if ((Object)(object)value.Line != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value.Line).gameObject);
				}
			}
		}

		private void LocalTouchCheck()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB local = Local;
			if ((Object)(object)local == (Object)null || local.isPlayerDead || !local.isPlayerControlled || threads.Count == 0 || carries.ContainsKey((int)local.playerClientId))
			{
				return;
			}
			Vector3 position = ((Component)local).transform.position;
			foreach (ThreadInfo value in threads.Values)
			{
				if (!(Time.time - value.TouchSent < 1.5f))
				{
					float num = position.x - value.Bottom.x;
					float num2 = position.z - value.Bottom.z;
					if (!(num * num + num2 * num2 > 0.20249999f) && !(position.y > value.TopY) && !(position.y + 2f < value.Bottom.y))
					{
						value.TouchSent = Time.time;
						Plugin.Log.LogInfo((object)$"[AngelColgante] Tocaste el hilo {value.Id}");
						AngelNet.ToServer(new AngelNet.Packet
						{
							Type = AngelNet.M.Touch,
							A = value.Id
						});
						break;
					}
				}
			}
		}

		internal static void ServerOnTouch(int player, int id)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (player >= 0 && threads.TryGetValue(id, out var value))
			{
				PlayerControllerB obj = AngelNet.Player(player);
				Vector3 bellPos = ((obj != null) ? ((Component)obj).transform.position : value.Bottom);
				AngelNet.Broadcast(new AngelNet.Packet
				{
					Type = AngelNet.M.ThreadRemove,
					A = id,
					B = 1
				});
				ServerMark(player, bellPos, ring: true, L.T("tocar un hilo", "touched a thread"));
			}
		}

		internal static void LocalSwing(PlayerControllerB holder)
		{
			//IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0053: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)holder == (Object)null || (Object)(object)holder != (Object)(object)Local || (Object)(object)holder.gameplayCamera == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)holder.gameplayCamera).transform;
			Vector3 position = transform.position;
			Vector3 q = transform.position + transform.forward * 2.2f;
			Vector3 q2 = default(Vector3);
			foreach (ThreadInfo value in threads.Values)
			{
				Vector3 bottom = value.Bottom;
				((Vector3)(ref q2))..ctor(value.Bottom.x, Mathf.Min(value.TopY, transform.position.y + 2.5f), value.Bottom.z);
				if (SegSegDistance(position, q, bottom, q2) < 0.55f)
				{
					Plugin.Log.LogInfo((object)$"[AngelColgante] Cortaste el hilo {value.Id}");
					AngelNet.ToServer(new AngelNet.Packet
					{
						Type = AngelNet.M.Cut,
						A = value.Id,
						B = -1
					});
					return;
				}
			}
			foreach (Carry value2 in carries.Values)
			{
				for (int i = 0; i < value2.Ties; i++)
				{
					if (value2.IsTied(i))
					{
						TiePoints(value2, i, out var p, out var p2);
						if (SegSegDistance(position, q, p, p2) < 0.55f)
						{
							Plugin.Log.LogInfo((object)$"[AngelColgante] Cortaste el hilo {i} que ataba al jugador {value2.Player}");
							value2.Untied[i] = true;
							AngelNet.ToServer(new AngelNet.Packet
							{
								Type = AngelNet.M.Cut,
								A = i,
								B = value2.Player
							});
							return;
						}
					}
				}
			}
		}

		internal static void ServerOnCut(int player, int id, int victim)
		{
			if (victim < 0)
			{
				if (threads.ContainsKey(id))
				{
					AngelNet.Broadcast(new AngelNet.Packet
					{
						Type = AngelNet.M.ThreadRemove,
						A = id,
						B = 0
					});
				}
			}
			else
			{
				ServerOnUntie(victim, id);
			}
		}

		internal static bool IsCovered(PlayerControllerB p)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			if (p.isInsideFactory || p.isInHangarShipRoom || p.isInElevator)
			{
				return true;
			}
			StartOfRound instance = StartOfRound.Instance;
			return Physics.Raycast(((Component)p).transform.position + Vector3.up * 2.1f, Vector3.up, 150f, instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1);
		}

		internal static void ServerMark(int player, Vector3 bellPos, bool ring, string why)
		{
			//IL_00be: 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)
			PlayerControllerB val = AngelNet.Player(player);
			if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && val.isPlayerControlled && !carries.ContainsKey(player) && (!serverMarkCooldown.TryGetValue(player, out var value) || !(Time.time < value)) && (!serverMarks.ContainsKey(player) || ring))
			{
				serverMarks[player] = Time.time + Plugin.MarkSeconds.Value;
				Plugin.Log.LogInfo((object)$"[AngelColgante] Jugador {player} ({val.playerUsername}) marcado por {why}");
				AngelNet.Broadcast(new AngelNet.Packet
				{
					Type = AngelNet.M.Mark,
					A = player,
					F = Plugin.MarkSeconds.Value,
					V = bellPos,
					B = (ring ? 1 : 0)
				});
			}
		}

		internal static void ServerClearMark(int player)
		{
			if (serverMarks.Remove(player))
			{
				AngelNet.Broadcast(new AngelNet.Packet
				{
					Type = AngelNet.M.ClearMark,
					A = player
				});
			}
		}

		private static void ServerMarks(StartOfRound sor)
		{
			if (serverMarks.Count == 0)
			{
				return;
			}
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, float> serverMark in serverMarks)
			{
				PlayerControllerB val = AngelNet.Player(serverMark.Key);
				if (Time.time > serverMark.Value || (Object)(object)val == (Object)null || val.isPlayerDead || !val.isPlayerControlled)
				{
					list.Add(serverMark.Key);
				}
			}
			foreach (int item in list)
			{
				Plugin.Log.LogInfo((object)$"[AngelColgante] Termina la marca del jugador {item}");
				ServerClearMark(item);
			}
		}

		internal static int ServerChooseTarget(out bool covered)
		{
			covered = false;
			int num = -1;
			int num2 = -1;
			float num3 = float.MaxValue;
			float num4 = float.MaxValue;
			foreach (KeyValuePair<int, float> serverMark in serverMarks)
			{
				PlayerControllerB val = AngelNet.Player(serverMark.Key);
				if ((Object)(object)val == (Object)null || val.isPlayerDead || !val.isPlayerControlled || carries.ContainsKey(serverMark.Key))
				{
					continue;
				}
				if (IsCovered(val))
				{
					if (serverMark.Value < num4)
					{
						num4 = serverMark.Value;
						num2 = serverMark.Key;
					}
				}
				else if (serverMark.Value < num3)
				{
					num3 = serverMark.Value;
					num = serverMark.Key;
				}
			}
			if (num >= 0)
			{
				return num;
			}
			covered = num2 >= 0;
			return num2;
		}

		internal static void OnMark(int player, float seconds, Vector3 bellPos, int ring)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (ring != 0)
			{
				PlayBell(bellPos);
			}
			if (!marks.TryGetValue(player, out var value))
			{
				value = new MarkInfo();
				value.Halo = AngelAssets.NewMeshObject("AngelHaloJugador", null, AngelAssets.TorusMesh, AngelAssets.Halo, shadows: false);
				value.Halo.transform.localScale = Vector3.one * 0.3f;
				value.HaloLight = AngelAssets.NewLight("LuzHalo", value.Halo.transform, (HDLightTypeAndShape)0, new Color(1f, 0.85f, 0.45f), 220f * Mathf.Max(0f, Plugin.HaloGlow.Value), 5f);
				if ((Object)(object)value.HaloLight != (Object)null)
				{
					((Component)value.HaloLight).transform.localPosition = Vector3.zero;
				}
				marks[player] = value;
			}
			value.Expire = Time.time + seconds;
		}

		internal static void OnClearMark(int player)
		{
			if (marks.TryGetValue(player, out var value))
			{
				marks.Remove(player);
				if ((Object)(object)value.Halo != (Object)null)
				{
					Object.Destroy((Object)(object)value.Halo);
				}
			}
		}

		private void DrawHalos()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_014b: 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)
			if (marks.Count == 0)
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, MarkInfo> mark in marks)
			{
				PlayerControllerB val = AngelNet.Player(mark.Key);
				MarkInfo value = mark.Value;
				if ((Object)(object)val == (Object)null || val.isPlayerDead || Time.time > value.Expire + 5f)
				{
					(list ?? (list = new List<int>())).Add(mark.Key);
				}
				else if (!((Object)(object)value.Halo == (Object)null))
				{
					float num = (((Object)(object)val.playerGlobalHead != (Object)null) ? (val.playerGlobalHead.position.y - ((Component)val).transform.position.y) : 1.9f);
					value.HeadY = ((value.HeadY < 0f) ? num : Mathf.Lerp(value.HeadY, num, 1f - Mathf.Exp(-1.5f * Time.deltaTime)));
					value.Halo.transform.position = ((Component)val).transform.position + Vector3.up * (value.HeadY + 0.95f + Mathf.Sin(Time.time * 1.6f) * 0.04f);
					value.Halo.transform.rotation = Quaternion.Euler(0f, Time.time * 40f, 0f);
					float num2 = value.Expire - Time.time;
					value.Halo.SetActive(num2 > 10f || Mathf.Repeat(Time.time, 0.5f) < 0.33f);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				OnClearMark(item);
			}
		}

		internal static void PlayBell(Vector3 pos)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_007f: Expected O, but got Unknown
			if (Plugin.BellClips.Count != 0)
			{
				AudioClip val = Plugin.BellClips[Random.Range(0, Plugin.BellClips.Count)];
				GameObject val2 = new GameObject("AngelCampana");
				val2.transform.position = pos;
				AudioSource obj = AngelAssets.NewSource(val2, Plugin.BellDistance.Value);
				obj.minDistance = 10f;
				obj.PlayOneShot(val, Mathf.Clamp01(Plugin.Volume.Value));
				Object.Destroy((Object)val2, val.length + 0.5f);
			}
		}

		internal static void ServerGrab(int player, ulong angelId, Vector3 start, float yaw)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			serverMarks.Remove(player);
			AngelNet.Broadcast(new AngelNet.Packet
			{
				Type = AngelNet.M.Grab,
				A = player,
				Id = angelId,
				V = start,
				F = yaw
			});
		}

		internal static void OnGrab(int player, ulong angelId, Vector3 start, float yaw)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			OnClearMark(player);
			if (carries.TryGetValue(player, out var value))
			{
				LineRenderer[] lines = value.Lines;
				foreach (LineRenderer val in lines)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
			}
			Carry carry = new Carry
			{
				Player = player,
				AngelId = angelId,
				Start = start,
				Yaw = yaw,
				T0 = Time.time,
				Ties = Mathf.Clamp(Plugin.Hits.Value, 1, 3)
			};
			for (int j = 0; j < carry.Ties; j++)
			{
				carry.Lines[j] = AngelAssets.NewLine("AngelAtadura" + j, ((Object)(object)Instance != (Object)null) ? ((Component)Instance).transform : null, Mathf.Max(0.01f, Plugin.ThreadWidth.Value * 1.2f));
				((Renderer)carry.Lines[j]).enabled = false;
			}
			carries[player] = carry;
			Plugin.Log.LogInfo((object)$"[AngelColgante] Jugador {player} atrapado en {start}");
			if (player == AngelNet.LocalIndex && (Object)(object)Instance != (Object)null)
			{
				Instance.localHits = 0;
				Instance.untieTarget = -1;
				Array.Clear(Instance.untieProg, 0, 3);
			}
		}

		internal static void ServerOnUntie(int player, int k)
		{
			if (carries.TryGetValue(player, out var value) && k >= 0 && k < value.Ties && !(value.Elapsed < 0.3f + (float)k * 0.5f))
			{
				AngelNet.Broadcast(new AngelNet.Packet
				{
					Type = AngelNet.M.Untied,
					A = player,
					B = k
				});
			}
		}

		internal static void OnUntied(int player, int k)
		{
			if (!carries.TryGetValue(player, out var value) || k < 0 || k >= 3)
			{
				return;
			}
			value.Untied[k] = true;
			Plugin.Log.LogInfo((object)$"[AngelColgante] Jugador {player}: hilo {k} desatado");
			if (!AngelNet.IsServer)
			{
				return;
			}
			bool flag = true;
			for (int i = 0; i < value.Ties; i++)
			{
				if (!value.Untied[i])
				{
					flag = false;
				}
			}
			if (flag)
			{
				ServerRelease(player, safe: true);
			}
		}

		internal static void ServerRelease(int player, bool safe)
		{
			if (carries.ContainsKey(player))
			{
				serverMarks.Remove(player);
				serverMarkCooldown[player] = Time.time + 20f;
				AngelNet.Broadcast(new AngelNet.Packet
				{
					Type = AngelNet.M.Release,
					A = player,
					B = (safe ? 1 : 0)
				});
			}
		}

		internal static void OnRelease(int player, int safe)
		{
			if (!carries.TryGetValue(player, out var value))
			{
				return;
			}
			carries.Remove(player);
			LineRenderer[] lines = value.Lines;
			foreach (LineRenderer val in lines)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			if (safe == 0)
			{
				dropped[player] = Time.time;
			}
			Plugin.Log.LogInfo((object)string.Format("[AngelColgante] Jugador {0} liberado ({1}, altura {2:0.0} m)", player, (safe != 0) ? "se desato" : "lo solto", value.Lift));
			if (player == AngelNet.LocalIndex && (Object)(object)Instance != (Object)null)
			{
				PlayerControllerB local = Local;
				if ((Object)(object)local != (Object)null)
				{
					local.disableMoveInput = false;
				}
				Instance.wasCarried = false;
				Instance.safeFallUntil = ((safe != 0 && Plugin.SafeFall.Value) ? (Time.time + 10f) : 0f);
			}
		}

		private static void TiePoints(Carry c, int k, out Vector3 p0, out Vector3 p1)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = AngelNet.Player(c.Player);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : c.Start);
			Quaternion val3 = Quaternion.Euler(0f, c.Yaw, 0f);
			p0 = val2 + val3 * (Vector3)(k switch
			{
				1 => new Vector3(0.42f, 1.05f, 0.3f), 
				0 => new Vector3(-0.42f, 1.05f, 0.3f), 
				_ => new Vector3(0f, 1.3f, 0.34f), 
			});
			AngelEnemy angelEnemy = AngelEnemy.Find(c.AngelId);
			p1 = (((Object)(object)angelEnemy != (Object)null) ? angelEnemy.TieAnchor(k) : (val2 + Vector3.up * 3f));
		}

		private void DrawCarries()
		{
			//IL_0052: 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)
			foreach (Carry value in carries.Values)
			{
				for (int i = 0; i < value.Ties; i++)
				{
					LineRenderer val = value.Lines[i];
					if (!((Object)(object)val == (Object)null) && (((Renderer)val).enabled = value.IsTied(i)))
					{
						TiePoints(value, i, out var p, out var p2);
						val.SetPosition(0, p);
						val.SetPosition(1, p2);
					}
				}
			}
		}

		private void LocalCarryMove()
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB local = Local;
			if ((Object)(object)local == (Object)null)
			{
				return;
			}
			int key = (int)local.playerClientId;
			if (carries.TryGetValue(key, out var value) && !local.isPlayerDead)
			{
				wasCarried = true;
				while (localHits < value.Ties && value.Elapsed >= 0.3f + (float)localHits * 0.5f)
				{
					localHits++;
					local.DamagePlayer(Mathf.Max(0, Plugin.Damage.Value), true, true, (CauseOfDeath)4, 0, false, default(Vector3));
					if (local.isPlayerDead)
					{
						return;
					}
				}
				local.disableMoveInput = true;
				((Component)local).transform.position = value.Start + Vector3.up * value.Lift;
				local.fallValue = 0f;
				local.fallValueUncapped = 0f;
				local.takingFallDamage = false;
				local.externalForces = Vector3.zero;
			}
			else if (wasCarried)
			{
				wasCarried = false;
				local.disableMoveInput = false;
			}
			if (safeFallUntil > 0f && !local.isPlayerDead)
			{
				if (Time.time > safeFallUntil || ((Object)(object)local.thisController != (Object)null && local.thisController.isGrounded && Time.time > safeFallUntil - 9.5f))
				{
					safeFallUntil = 0f;
					return;
				}
				local.fallValueUncapped = Mathf.Max(local.fallValueUncapped, -20f);
				local.takingFallDamage = false;
			}
		}

		private void LocalUntie()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB local = Local;
			if ((Object)(object)local == (Object)null || local.isPlayerDead || !carries.TryGetValue((int)local.playerClientId, out var value) || value.Elapsed < value.AttachDuration)
			{
				if (untieTarget >= 0 || fillShown)
				{
					SetFill(0f);
				}
				untieTarget = -1;
				return;
			}
			Transform transform = ((Component)local.gameplayCamera).transform;
			int num = -1;
			float num2 = 22f;
			for (int i = 0; i < value.Ties; i++)
			{
				if (!value.IsTied(i))
				{
					continue;
				}
				TiePoints(value, i, out var p, out var p2);
				for (int j = 0; j <= 12; j++)
				{
					Vector3 val = Vector3.Lerp(p, p2, (float)j / 12f);
					float num3 = Vector3.Angle(transform.forward, val - transform.position);
					if (i == untieTarget)
					{
						num3 -= 8f;
					}
					if (num3 < num2)
					{
						num2 = num3;
						num = i;
					}
				}
			}
			if (num < 0 && untieTarget >= 0 && value.IsTied(untieTarget) && Time.time - lastOnTarget < 0.4f)
			{
				num = untieTarget;
			}
			if (num >= 0)
			{
				lastOnTarget = Time.time;
			}
			if (num != untieTarget)
			{
				untieTarget = num;
				if (num >= 0)
				{
					Plugin.Log.LogInfo((object)$"[AngelColgante] Mirando el hilo {num}");
				}
			}
			bool flag = false;
			try
			{
				InputAction obj = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Interact", false);
				flag = obj != null && obj.IsPressed();
			}
			catch
			{
			}
			try
			{
				if (!flag && Keyboard.current != null)
				{
					flag = ((ButtonControl)Keyboard.current.eKey).isPressed;
				}
			}
			catch
			{
			}
			float num4 = Mathf.Max(0.1f, Plugin.UntieSeconds.Value);
			for (int k = 0; k < 3; k++)
			{
				if (!flag || k != num)
				{
					untieProg[k] = Mathf.Max(0f, untieProg[k] - Time.deltaTime * 0.5f);
				}
			}
			if (flag && num >= 0)
			{
				if (untieProg[num] == 0f)
				{
					Plugin.Log.LogInfo((object)$"[AngelColgante] Desatando el hilo {num}");
				}
				untieProg[num] += Time.deltaTime;
				SetFill(untieProg[num] / num4);
				if (untieProg[num] >= num4)
				{
					value.Untied[num] = true;
					AngelNet.ToServer(new AngelNet.Packet
					{
						Type = AngelNet.M.Untie,
						A = num
					});
					untieProg[num] = 0f;
					untieTarget = -1;
					SetFill(0f);
				}
			}
			else if (fillShown)
			{
				SetFill(0f);
			}
		}

		private void SetFill(float f)
		{
			fillShown = f > 0f;
			try
			{
				HUDManager instance = HUDManager.Instance;
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.holdInteractionFillAmount != (Object)null)
				{
					instance.holdInteractionFillAmount.fillAmount = Mathf.Clamp01(f);
				}
			}
			catch
			{
			}
		}

		private void CheckDroppedDeaths()
		{
			if (dropped.Count == 0)
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, float> item in dropped)
			{
				PlayerControllerB val = AngelNet.Player(item.Key);
				if ((Object)(object)val == (Object)null || Time.time - item.Value > 15f)
				{
					(list ?? (list = new List<int>())).Add(item.Key);
				}
				else if (val.isPlayerDead && !((Object)(object)val.deadBody == (Object)null))
				{
					(list ?? (list = new List<int>())).Add(item.Key);
					if (Plugin.HangCorpse.Value)
					{
						HangBody(val.deadBody);
					}
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item2 in list)
			{
				dropped.Remove(item2);
			}
		}

		private void HangBody(DeadBodyInfo body)
		{
			//IL_0140: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Rigidbody val = null;
				string[] array = new string[4] { "neck", "head", "spine.004", "spine.003" };
				Rigidbody[] bodyParts;
				foreach (string value in array)
				{
					bodyParts = body.bodyParts;
					foreach (Rigidbody val2 in bodyParts)
					{
						if ((Object)(object)val2 != (Object)null && ((Object)val2).name.ToLowerInvariant().Contains(value))
						{
							val = val2;
							break;
						}
					}
					if ((Object)(object)val != (Object)null)
					{
						break;
					}
				}
				if ((Object)(object)val == (Object)null && body.bodyParts.Length != 0)
				{
					val = body.bodyParts[0];
				}
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				List<string> list = new List<string>();
				bodyParts = body.bodyParts;
				foreach (Rigidbody val3 in bodyParts)
				{
					if ((Object)(object)val3 != (Object)null)
					{
						list.Add(((Object)val3).name);
					}
				}
				Plugin.Log.LogInfo((object)("[AngelColgante] Colgando el cadaver de " + ((Object)val).name + " (partes: " + string.Join(", ", list) + ")"));
				Vector3 position = val.position;
				float num = AngelEnemy.GroundAt(position, position.y + 2f);
				Transform transform = new GameObject("AngelSoga").transform;
				transform.position = new Vector3(position.x, num + 2f, position.z);
				body.attachedLimb = val;
				body.attachedTo = transform;
				body.matchPositionExactly = true;
				LineRenderer line = AngelAssets.NewLine("AngelSogaHilo", ((Component)this).transform, Mathf.Max(0.008f, Plugin.ThreadWidth.Value));
				hanged.Add(new Hanged
				{
					Body = body,
					Anchor = transform,
					Neck = val,
					Line = line
				});
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[AngelColgante] No se pudo colgar el cadaver: " + ex.Message));
			}
		}

		private void DrawHanged()
		{
			//IL_00b8: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			for (int num = this.hanged.Count - 1; num >= 0; num--)
			{
				Hanged hanged = this.hanged[num];
				if ((Object)(object)hanged.Body == (Object)null || (Object)(object)hanged.Neck == (Object)null || hanged.Body.deactivated || (Object)(object)hanged.Body.attachedTo != (Object)(object)hanged.Anchor)
				{
					if ((Object)(object)hanged.Line != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)hanged.Line).gameObject);
					}
					if ((Object)(object)hanged.Anchor != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)hanged.Anchor).gameObject);
					}
					this.hanged.RemoveAt(num);
				}
				else
				{
					hanged.Line.SetPosition(0, hanged.Neck.position);
					hanged.Line.SetPosition(1, hanged.Anchor.position + Vector3.up * 220f);
				}
			}
		}

		internal static void OnBeam(Vector3 ground, float seconds)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0123: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Instance == (Object)null))
			{
				GameObject val = new GameObject("AngelHazDeLuz");
				val.transform.position = ground;
				GameObject val2 = AngelAssets.NewMeshObject("Columna", val.transform, AngelAssets.BeamMesh, AngelAssets.Beam, shadows: false);
				val2.transform.localScale = new Vector3(2.2f, 220f, 2.2f);
				Light val3 = AngelAssets.NewLight("LuzHaz", val.transform, (HDLightTypeAndShape)3, new Color(1f, 0.93f, 0.78f), 30000f, 140f);
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).transform.localPosition = Vector3.up * 90f;
					((Component)val3).transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
					val3.spotAngle = 12f;
				}
				Instance.beams.Add((val, Time.time, seconds, val3, val2.GetComponent<MeshRenderer>()));
				PlayBell(ground + Vector3.up * 20f);
				Plugin.Log.LogInfo((object)$"[AngelColgante] Haz de luz en {ground}");
			}
		}

		private void UpdateBeams()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			for (int num = beams.Count - 1; num >= 0; num--)
			{
				(GameObject, float, float, Light, MeshRenderer) tuple = beams[num];
				float num2 = (Time.time - tuple.Item2) / tuple.Item3;
				if ((Object)(object)tuple.Item1 == (Object)null || num2 >= 1f)
				{
					if ((Object)(object)tuple.Item1 != (Object)null)
					{
						Object.Destroy((Object)(object)tuple.Item1);
					}
					beams.RemoveAt(num);
				}
				else
				{
					float num3 = Mathf.Clamp01((Time.time - tuple.Item2) / 1.5f) * Mathf.Clamp01((1f - num2) / 0.3f);
					if ((Object)(object)tuple.Item5 != (Object)null)
					{
						((Renderer)tuple.Item5).GetPropertyBlock(mpb);
						mpb.SetColor("_UnlitColor", new Color(1f, 0.93f, 0.75f, 0.22f * num3));
						((Renderer)tuple.Item5).SetPropertyBlock(mpb);
					}
					if ((Object)(object)tuple.Item4 != (Object)null)
					{
						tuple.Item4.intensity = 30000f * num3;
					}
				}
			}
		}

		private static float SegSegDistance(Vector3 p1, Vector3 q1, Vector3 p2, Vector3 q2)
		{
			//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_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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0020: 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_0029: 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_006b: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = q1 - p1;
			Vector3 val2 = q2 - p2;
			Vector3 val3 = p1 - p2;
			float num = Vector3.Dot(val, val);
			float num2 = Vector3.Dot(val2, val2);
			float num3 = Vector3.Dot(val2, val3);
			if (num <= 1E-06f && num2 <= 1E-06f)
			{
				return ((Vector3)(ref val3)).magnitude;
			}
			float num4;
			float num5;
			if (num <= 1E-06f)
			{
				num4 = 0f;
				num5 = Mathf.Clamp01(num3 / num2);
			}
			else
			{
				float num6 = Vector3.Dot(val, val3);
				if (num2 <= 1E-06f)
				{
					num5 = 0f;
					num4 = Mathf.Clamp01((0f - num6) / num);
				}
				else
				{
					float num7 = Vector3.Dot(val, val2);
					float num8 = num * num2 - num7 * num7;
					num4 = ((num8 != 0f) ? Mathf.Clamp01((num7 * num3 - num6 * num2) / num8) : 0f);
					num5 = (num7 * num4 + num3) / num2;
					if (num5 < 0f)
					{
						num5 = 0f;
						num4 = Mathf.Clamp01((0f - num6) / num);
					}
					else if (num5 > 1f)
					{
						num5 = 1f;
						num4 = Mathf.Clamp01((num7 - num6) / num);
					}
				}
			}
			Vector3 val4 = p1 + val * num4 - (p2 + val2 * num5);
			return ((Vector3)(ref val4)).magnitude;
		}
	}
	public class AngelEnemy : EnemyAI
	{
		internal enum S
		{
			Spawning,
			Patrol,
			Hunt,
			Wait,
			Grab,
			Carry,
			Return
		}

		private class Wing
		{
			internal Transform Cable;

			internal Transform Body;

			internal Vector3 Axis;

			internal float Phase;

			internal float FlapStart = -10f;

			internal float FlapSign = 1f;
		}

		internal static EnemyType Type;

		internal static GameObject Prefab;

		internal static readonly List<AngelEnemy> All = new List<AngelEnemy>();

		internal S state;

		internal int targetIdx = -1;

		private float stateTime;

		private const float HangGap = 2.4f;

		private Transform visual;

		private LineRenderer mainThread;

		private Light glow;

		private MaterialPropertyBlock mpb;

		private AudioSource loopCalm;

		private AudioSource loopAggro;

		private float aggro;

		private Vector3 netPos;

		private bool hasNetPos;

		private Vector3 patrolDest;

		private float patrolDestTime;

		private float groundY;

		private float groundCheckTime;

		private float nextThread;

		private int threadTarget = 40;

		private float threadInterval = 4f;

		private float nextPosSync;

		private float spawnTargetY;

		private Vector3 waitPoint;

		private Vector3 lastTargetPos;

		private int lastTargetIdx = -1;

		private float targetSpeed;

		private float nextSpeedLog;

		private float coverTimer;

		private float nextNoise;

		private int noiseCount;

		private readonly List<Wing> wings = new List<Wing>();

		private readonly List<MeshRenderer> renderers = new List<MeshRenderer>();

		private float nextFlap;

		internal static float Scale => Mathf.Max(0.5f, Plugin.Size.Value) / 1.085f;

		internal static float RingDrop => 1.067f * Scale;

		private bool Aggressive
		{
			get
			{
				if (state != S.Hunt && state != S.Grab)
				{
					return state == S.Carry;
				}
				return true;
			}
		}

		internal static void Register()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00be: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			Prefab = NetworkPrefabs.CreateNetworkPrefab("AngelColgante");
			AngelEnemy angelEnemy = Prefab.AddComponent<AngelEnemy>();
			NavMeshAgent val = Prefab.AddComponent<NavMeshAgent>();
			((Behaviour)val).enabled = false;
			((EnemyAI)angelEnemy).agent = val;
			AudioSource val2 = Prefab.AddComponent<AudioSource>();
			val2.playOnAwake = false;
			val2.spatialBlend = 1f;
			((EnemyAI)angelEnemy).creatureVoice = val2;
			((EnemyAI)angelEnemy).creatureSFX = val2;
			Transform transform = new GameObject("Eye").transform;
			transform.SetParent(Prefab.transform, false);
			transform.localPosition = new Vector3(0f, 0f - RingDrop + 0.3f * Scale, 0f);
			((EnemyAI)angelEnemy).eye = transform;
			GameObject val3 = new GameObject("ScanNode")
			{
				layer = 22
			};
			val3.transform.SetParent(Prefab.transform, false);
			val3.transform.localPosition = new Vector3(0f, 0f - RingDrop + 0.28f * Scale, 0f);
			BoxCollider obj = val3.AddComponent<BoxCollider>();
			((Collider)obj).isTrigger = true;
			obj.size = Vector3.one * 1.2f;
			ScanNodeProperties obj2 = val3.AddComponent<ScanNodeProperties>();
			obj2.headerText = L.T("Ángel Colgante", "Hanging Angel");
			obj2.subText = "";
			obj2.nodeType = 1;
			obj2.minRange = 1;
			obj2.maxRange = 110;
			obj2.requiresLineOfSight = true;
			obj2.creatureScanID = -1;
			Type = ScriptableObject.CreateInstance<EnemyType>();
			((Object)Type).name = "AngelColganteType";
			Type.enemyName = L.T("Ángel Colgante", "Hanging Angel");
			Type.enemyPrefab = Prefab;
			Type.PowerLevel = 2f;
			Type.MaxCount = 1;
			Type.isOutsideEnemy = true;
			Type.isDaytimeEnemy = false;
			Type.canDie = false;
			Type.canBeStunned = false;
			Type.canBeDestroyed = false;
			Type.destroyOnDeath = false;
			Type.canSeeThroughFog = true;
			Type.stunTimeMultiplier = 1f;
			Type.doorSpeedMultiplier = 1f;
			Type.loudnessMultiplier = 1f;
			Type.normalizedTimeInDayToLeave = 1f;
			Type.spawnInGroupsOf = 1;
			Type.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f);
			Type.numberSpawnedFalloff = AnimationCurve.Constant(0f, 1f, 1f);
			Type.audioClips = (AudioClip[])(object)new AudioClip[0];
			Type.miscAnimations = (MiscAnimation[])(object)new MiscAnimation[0];
			((EnemyAI)angelEnemy).enemyType = Type;
			((EnemyAI)angelEnemy).enemyHP = 100;
			((EnemyAI)angelEnemy).AIIntervalTime = 0.2f;
			((EnemyAI)angelEnemy).enemyBehaviourStates = (EnemyBehaviourState[])(object)new EnemyBehaviourState[0];
			((EnemyAI)angelEnemy).skinnedMeshRenderers = (SkinnedMeshRenderer[])(object)new SkinnedMeshRenderer[0];
			((EnemyAI)angelEnemy).meshRenderers = (MeshRenderer[])(object)new MeshRenderer[0];
			TerminalNode val4 = ScriptableObject.CreateInstance<TerminalNode>();
			val4.clearPreviousText = true;
			val4.maxCharactersToType = 35;
			val4.creatureName = Type.enemyName;
			val4.displayText = L.T("ÁNGEL COLGANTE\n\nNivel de peligro: 70%\nNombre científico: Desconocido\n\nLos Ángeles Colgantes son entidades aéreas de origen desconocido, compuestas por una agrupación de alas blancas suspendidas mediante numerosos filamentos. Aunque inicialmente fueron confundidos con organismos voladores, observaciones posteriores revelaron que sus alas no parecen contribuir a su desplazamiento. En cambio, estas cuelgan de una estructura cruciforme prácticamente transparente, cuya presencia solo ha podido identificarse por la disposición de los filamentos que la rodean.\n\nNo se ha determinado si las alas pertenecen a un mismo organismo, ni si alguna vez estuvieron unidas a uno.\n\nLos Ángeles Colgantes aparecen generalmente durante la tarde, descendiendo a través de una columna de luz de origen desconocido. Una vez alcanzada cierta altura, permanecen suspendidos y se desplazan lentamente por el entorno, liberando filamentos casi invisibles que desaparecen después de un tiempo. Estos filamentos parecen reaccionar a la proximidad de organismos vivos, aunque se desconoce el mecanismo que permite esta detección.\n\nEl contacto con uno de ellos produce un fenómeno particularmente difícil de explicar. Los individuos afectados presentan un anillo luminoso sobre la cabeza, acompañado por el sonido de campanas que no parece proceder de ninguna fuente física identificable. Poco después, el Ángel Colgante abandona su comportamiento pasivo y comienza a aproximarse al individuo marcado.\n\nDurante este estado, todas sus alas se agitan de forma violenta, aunque el movimiento de la entidad parece permanecer independiente de ellas. Se ha observado que evita perseguir objetivos bajo estructuras cubiertas, permaneciendo a cierta distancia hasta que estos vuelven a quedar expuestos.\n\nAl alcanzar a su objetivo, la entidad fija tres filamentos al cuerpo de la víctima y comienza a elevarse. Los individuos capturados permanecen conscientes y conservan cierta movilidad, lo que les permite desprenderse de los filamentos. De no hacerlo, son liberados desde alturas que generalmente resultan mortales.\n\nSe desconoce el propósito de este comportamiento. No se ha observado que los Ángeles Colgantes consuman a sus víctimas, recolecten sus restos o manifiesten interés alguno por los cuerpos después de soltarlos.\n\nAlgunos investigadores han propuesto que la estructura visible no constituye al organismo completo, sino únicamente una parte de él. Esta hipótesis se basa en la aparente tensión de los filamentos superiores, que parecen prolongarse hacia un punto situado por encima de la entidad. Hasta la fecha, no se ha logrado identificar dicho punto ni determinar si realmente existe.\n\nNota de Sigurd:\n\nAl principio pense que eran pajaros atrapados en algo. No se mueven como pajaros.\n\nNo se como explicarlo. Las alas se agitan, pero la cosa sigue moviendose exactamente igual. Como si alguien la estuviera llevando.\n\nRich dice que vio los hilos subir hasta desaparecer. Le pregunte que habia arriba y dijo que nada.\n\nSi escuchan las campanas, CORRAN A UN TECHO. No intenten mirar hacia arriba para averiguar de donde vienen.\n\nNo creo que sea buena idea que sepan que los estamos mirando.\n\n", "HANGING ANGEL\n\nDanger level: 70%\nScientific name: Unknown\n\nHanging Angels are aerial entities of unknown origin, made up of a cluster of white wings suspended by numerous filaments. Although they were first mistaken for flying organisms, later observations revealed that their wings do not appear to contribute to their movement. Instead, they hang from a nearly transparent cross-shaped structure whose presence has only been inferred from the arrangement of the filaments around it.\n\nIt has not been determined whether the wings belong to a single organism, or whether they were ever attached to one.\n\nHanging Angels usually appear in the afternoon, descending through a column of light of unknown origin. Once they reach a certain height, they remain suspended and drift slowly through the area, releasing nearly invisible filaments that disappear after some time. These filaments seem to react to the proximity of living organisms, although the mechanism behind this detection is unknown.\n\nContact with one of them produces a phenomenon that is particularly hard to explain. Affected individuals display a luminous ring above their heads, accompanied by the sound of bells that does not seem to come from any identifiable physical source. Shortly afterwards, the Hanging Angel abandons its passive behavior and begins to approach the marked individual.\n\nIn this state, all of its wings flap violently, although the entity's movement appears to remain independent of them. It has been observed to avoid pursuing targets under covered structures, keeping its distance until they are exposed again.\n\nUpon reaching its target, the entity attaches three filaments to the victim's body and begins to rise. Captured individuals remain conscious and retain some mobility, which allows them to free themselves from the filaments. Those who fail to do so are released from heights that are usually fatal.\n\nThe purpose of this behavior is unknown. Hanging Angels have not been observed consuming their victims, collecting their remains or showing any interest in the bodies after releasing them.\n\nSome researchers have proposed that the visible structure is not the whole organism, but only part of it. This hypothesis is based on the apparent tension of the upper filaments, which seem to extend toward a point above the entity. To date, that point has not been identified, nor has it been determined whether it actually exists.\n\nSigurd's note:\n\nAt first i thought they were birds caught in something. They dont move like birds.\n\nI dont know how to explain it. The wings flap but the thing keeps moving exactly the same. Like someone is carrying it.\n\nRich says he saw the strings go up until they disappeared. I asked him what was up there and he said nothing.\n\nIf you hear the bells, RUN TO A ROOF. Dont try to look up to find out where theyre coming from.\n\nI dont think its a good idea to let them know were watching.\n\n");
			TerminalKeyword val5 = ScriptableObject.CreateInstance<TerminalKeyword>();
			val5.word = "angel";
			val5.isVerb = false;
			Enemies.RegisterEnemy(Type, 0, (LevelTypes)(-1), (SpawnType)2, val4, val5);
			Plugin.Log.LogInfo((object)$"[AngelColgante] Enemigo registrado (escala {Scale:0.00}, anillo a {RingDrop:0.00} m sobre las alas)");
		}

		internal static AngelEnemy Find(ulong id)
		{
			foreach (AngelEnemy item in All)
			{
				if ((Object)(object)item != (Object)null && ((NetworkBehaviour)item).NetworkObjectId == id)
				{
					return item;
				}
			}
			return null;
		}

		public override void Start()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				((EnemyAI)this).Start();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[AngelColgante] EnemyAI.Start: " + ex.Message));
			}
			All.Add(this);
			if ((Object)(object)base.agent != (Object)null)
			{
				((Behaviour)base.agent).enabled = false;
			}
			BuildVisual();
			netPos = ((Component)this).transform.position;
			if (((NetworkBehaviour)this).IsServer)
			{
				groundY = GroundAt(((Component)this).transform.position, ((Component)this).transform.position.y);
				spawnTargetY = groundY + Plugin.PatrolHeight.Value + RingDrop;
				nextThread = Time.time + 12f;
				ComputeThreadBudget();
				SetState(S.Spawning, -1);
			}
			Plugin.Log.LogInfo((object)$"[AngelColgante] Angel aparecio en {((Component)this).transform.position} (host={((NetworkBehaviour)this).IsServer}, suelo={groundY:0.0})");
		}

		public override void OnDestroy()
		{
			All.Remove(this);
			try
			{
				((EnemyAI)this).OnDestroy();
			}
			catch
			{
			}
		}

		private void BuildVisual()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_0317: 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_01dc: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			visual = new GameObject("Visual").transform;
			visual.SetParent(((Component)this).transform, false);
			float scale = Scale;
			Transform transform = new GameObject("Cuerpo").transform;
			transform.SetParent(visual, false);
			transform.localPosition = new Vector3(0f, -1.067f * scale, 0f);
			transform.localScale = Vector3.one * scale;
			Transform[] array = (Transform[])(object)new Transform[AngelAssets.Parts.Count];
			for (int i = 0; i < AngelAssets.Parts.Count; i++)
			{
				AngelAssets.Part part = AngelAssets.Parts[i];
				Transform parent = ((part.Parent >= 0) ? array[part.Parent] : transform);
				GameObject val = AngelAssets.NewMeshObject("Pieza" + i, parent, part.Mesh, AngelAssets.Body, shadows: true);
				val.transform.localPosition = ((part.Parent >= 0) ? (part.Pivot - AngelAssets.Parts[part.Parent].Pivot) : part.Pivot);
				val.layer = 19;
				array[i] = val.transform;
				renderers.Add(val.GetComponent<MeshRenderer>());
			}
			for (int j = 0; j < AngelAssets.Parts.Count; j++)
			{
				AngelAssets.Part part2 = AngelAssets.Parts[j];
				if (part2.Parent >= 0)
				{
					Vector3 val2 = AngelAssets.Parts[part2.Parent].Pivot;
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude < 1E-06f)
					{
						val2 = Vector3.right;
					}
					wings.Add(new Wing
					{
						Cable = array[part2.Parent],
						Body = array[j],
						Axis = Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized),
						Phase = Random.Range(0f, 10f)
					});
				}
			}
			nextFlap = Time.time + Random.Range(1f, 3f);
			GameObject obj = AngelAssets.NewMeshObject("Cruceta", visual, AngelAssets.CrossMesh, AngelAssets.Cross, shadows: false);
			obj.transform.localPosition = transform.localPosition;
			obj.transform.localScale = Vector3.one * scale;
			obj.layer = 19;
			mainThread = AngelAssets.NewLine("HiloPrincipal", ((Component)this).transform, Mathf.Max(0.004f, Plugin.ThreadWidth.Value * 0.8f));
			glow = AngelAssets.NewLight("LuzAlas", visual, (HDLightTypeAndShape)0, new Color(1f, 0.93f, 0.8f), 160f, 9f);
			if ((Object)(object)glow != (Object)null)
			{
				((Component)glow).transform.localPosition = new Vector3(0f, -1.067f * scale + 0.3f * scale, 0f);
			}
			mpb = new MaterialPropertyBlock();
			loopCalm = MakeLoop(base.creatureVoice, Plugin.NeutralClips, 60f);
			loopAggro = MakeLoop(null, Plugin.AggressiveClips, 95f);
		}

		public override void Update()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			float deltaTime = Time.deltaTime;
			stateTime += deltaTime;
			if (((NetworkBehaviour)this).IsServer)
			{
				ServerTick(deltaTime);
			}
			else if (hasNetPos)
			{
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, netPos, 1f - Mathf.Exp(-12f * deltaTime));
			}
			Animate(deltaTime);
			Sounds();
		}

		public override void DoAIInterval()
		{
		}

		private void Animate(float dt)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: 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_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)visual == (Object)null)
			{
				return;
			}
			aggro = Mathf.MoveTowards(aggro, Aggressive ? 1f : 0f, dt * 1.2f);
			float time = Time.time;
			float num = aggro * (Mathf.PerlinNoise(time * 6f, 0.3f) - 0.5f) * 10f;
			visual.localPosition = new Vector3(0f, Mathf.Sin(time * 0.8f) * 0.12f * (1f - aggro), 0f);
			visual.localRotation = Quaternion.Euler(Mathf.Sin(time * 0.37f) * Mathf.Lerp(1.5f, 4f, aggro) + num, Mathf.Sin(time * 0.11f) * 12f, Mathf.Sin(time * 0.29f + 1.3f) * Mathf.Lerp(1.2f, 4f, aggro) - num * 0.7f);
			if (aggro < 0.5f && wings.Count > 0 && time >= nextFlap)
			{
				Wing wing = wings[Random.Range(0, wings.Count)];
				wing.FlapStart = time;
				wing.FlapSign = ((Random.value < 0.5f) ? (-1f) : 1f);
				nextFlap = time + Random.Range(1.2f, 4f);
			}
			foreach (Wing wing2 in wings)
			{
				float num2 = time - wing2.FlapStart;
				float num3 = ((num2 < 2.2f) ? (30f * Mathf.Sin(num2 * 10f) * Mathf.Exp((0f - num2) * 2f) * wing2.FlapSign) : 0f);
				float num4 = Mathf.Sin(time * 0.6f + wing2.Phase) * 1.5f + num3 * 0.15f;
				float num5 = Mathf.Sin(time * 0.45f + wing2.Phase * 1.7f) * 2f + num3;
				float num6 = 0f - (14f + 9f * Mathf.Sin(time * 3.1f + wing2.Phase) + 8f * (Mathf.PerlinNoise(time * 4f, wing2.Phase) - 0.5f));
				float num7 = 38f * Mathf.Sin(time * 15f + wing2.Phase * 3f) + 10f * Mathf.Sin(time * 23f + wing2.Phase);
				float num8 = aggro * 15f * Mathf.Sin(time * 5f + wing2.Phase * 2f);
				wing2.Cable.localRotation = Quaternion.AngleAxis(Mathf.Lerp(num4, num6, aggro), wing2.Axis) * Quaternion.AngleAxis(num8, Vector3.up);
				wing2.Body.localRotation = Quaternion.AngleAxis(Mathf.Lerp(num5, num7, aggro), wing2.Axis);
			}
			float num9 = ((aggro > 0.5f) ? (0.75f + 0.5f * Mathf.Abs(Mathf.Sin(time * 5.5f))) : (0.85f + 0.2f * Mathf.Sin(time * 1.3f)));
			Color val = Color.Lerp(new Color(1f, 0.96f, 0.88f), new Color(1f, 0.97f, 0.92f), aggro) * (Mathf.Lerp(1.3f, 1.8f, aggro) * num9);
			foreach (MeshRenderer renderer in renderers)
			{
				if (!((Object)(object)renderer == (Object)null))
				{
					((Renderer)renderer).GetPropertyBlock(mpb);
					mpb.SetColor("_EmissiveColor", val);
					((Renderer)renderer).SetPropertyBlock(mpb);
				}
			}
			if ((Object)(object)glow != (Object)null)
			{
				glow.color = new Color(1f, 0.93f, 0.8f);
			}
			if ((Object)(object)mainThread != (Object)null)
			{
				Vector3 position = visual.position;
				mainThread.SetPosition(0, position);
				mainThread.SetPosition(1, position + Vector3.up * 220f);
			}
		}

		private AudioSource MakeLoop(AudioSource reuse, List<AudioClip> clips, float maxDistance)
		{
			if (clips.Count == 0)
			{
				return null;
			}
			AudioSource val = (((Object)(object)reuse != (Object)null) ? reuse : ((Component)this).gameObject.AddComponent<AudioSource>());
			val.playOnAwake = false;
			val.loop = true;
			val.spatialBlend = 1f;
			val.rolloffMode = (AudioRolloffMode)1;
			val.minDistance = 6f;
			val.maxDistance = maxDistance;
			val.dopplerLevel = 0f;
			val.clip = clips[Random.Range(0, clips.Count)];
			val.volume = 0f;
			val.time = Random.Range(0f, val.clip.length * 0.9f);
			val.Play();
			return val;
		}

		private void Sounds()
		{
			float num = Mathf.Clamp01(Plugin.Volume.Value);
			if ((Object)(object)loopAggro == (Object)null)
			{
				if ((Object)(object)loopCalm != (Object)null)
				{
					loopCalm.volume = num;
				}
				return;
			}
			if ((Object)(object)loopCalm != (Object)null)
			{
				loopCalm.volume = num * (1f - aggro);
			}
			loopAggro.volume = num * aggro;
		}

		internal void OnState(int st, int target)
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				if (st != (int)state)
				{
					stateTime = 0f;
				}
				state = (S)st;
				targetIdx = target;
			}
		}

		internal void OnPos(Vector3 pos, float _)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsServer)
			{
				netPos = pos;
				if (!hasNetPos)
				{
					((Component)this).transform.position = pos;
					hasNetPos = true;
				}
			}
		}

		private void SetState(S s, int target)
		{
			if (s != state || target != targetIdx)
			{
				Plugin.Log.LogInfo((object)$"[AngelColgante] Estado {state} -> {s} (objetivo {target})");
			}
			state = s;
			targetIdx = target;
			stateTime = 0f;
			AngelNet.Broadcast(new AngelNet.Packet
			{
				Type = AngelNet.M.State,
				Id = ((NetworkBehaviour)this).NetworkObjectId,
				A = (int)s,
				B = target
			});
		}

		private void ServerTick(float dt)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_076f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0780: Unknown result type (might be due to invalid IL or missing references)
			//IL_078a: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_068a: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0134: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: 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_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05db: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: 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_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_060a: Unknown result type (might be due to invalid