Decompiled source of MeinSchatz v0.2.0

plugins/MeinSchatz.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
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.Events;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Mein Schatz")]
[assembly: AssemblyCompany("TGamerT")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0-prototype")]
[assembly: AssemblyVersion("0.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CursedRingPrototype
{
	public sealed class CursedRingItem : GrabbableObject
	{
		internal bool Wearing;

		private float nextInput;

		private GameObject fingerRing;

		private bool visualWearing;

		public bool AiSafeToTest => false;

		public bool AiCanUse => Time.time >= nextInput;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (buttonDown && ((NetworkBehaviour)this).IsOwner && !((Object)(object)base.playerHeldBy == (Object)null) && !base.playerHeldBy.isPlayerDead && !(Time.time < nextInput))
			{
				nextInput = Time.time + 0.4f;
				RingNet.Request(this, RingMessage.Toggle);
			}
		}

		public override void ItemInteractLeftRight(bool right)
		{
			if (((NetworkBehaviour)this).IsOwner && Wearing && !((Object)(object)base.playerHeldBy == (Object)null) && !(Time.time < nextInput))
			{
				nextInput = Time.time + 0.5f;
				RingNet.Request(this, right ? RingMessage.Surrender : RingMessage.Shake);
			}
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			RingNet.RingSpawned(this);
		}

		public override void OnNetworkDespawn()
		{
			RingNet.RingDespawned(this);
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		public override void Update()
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (!((NetworkBehaviour)this).IsSpawned)
			{
				return;
			}
			base.isBeingUsed = Wearing;
			if (visualWearing != Wearing)
			{
				Transform val = ((Component)this).transform.Find("RingVisual");
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(!Wearing);
				}
				visualWearing = Wearing;
				if (!Wearing)
				{
					((GrabbableObject)this).EnableItemMeshes(!base.isPocketed);
				}
			}
			if (Wearing && (Object)(object)base.playerHeldBy != (Object)null)
			{
				if ((Object)(object)fingerRing == (Object)null)
				{
					fingerRing = RingVisualFactory.CreateRing(base.playerHeldBy.serverItemHolder);
					((Object)fingerRing).name = "DerEineRing_Angezogen";
					fingerRing.transform.localScale = Vector3.one * 0.24f;
					fingerRing.transform.localPosition = new Vector3(0.018f, -0.03f, 0.015f);
				}
			}
			else if ((Object)(object)fingerRing != (Object)null)
			{
				Object.Destroy((Object)(object)fingerRing);
				fingerRing = null;
			}
		}

		private void OnDisable()
		{
			if ((Object)(object)fingerRing != (Object)null)
			{
				Object.Destroy((Object)(object)fingerRing);
			}
		}
	}
	internal static class FaceAtlas
	{
		private static readonly int width;

		private static readonly int height;

		private static readonly byte[] rgb;

		static FaceAtlas()
		{
			using Stream stream = typeof(FaceAtlas).Assembly.GetManifestResourceStream("CursedRingPrototype.FaceAtlas");
			if (stream == null)
			{
				throw new InvalidDataException("Embedded face albedo is missing.");
			}
			using GZipStream input = new GZipStream(stream, CompressionMode.Decompress);
			using BinaryReader binaryReader = new BinaryReader(input);
			width = binaryReader.ReadInt32();
			height = binaryReader.ReadInt32();
			if (width < 2 || height < 2 || width > 4096 || height > 4096)
			{
				throw new InvalidDataException("Invalid face albedo dimensions.");
			}
			rgb = binaryReader.ReadBytes(checked(width * height * 3));
			if (rgb.Length != width * height * 3)
			{
				throw new InvalidDataException("Incomplete face albedo.");
			}
		}

		private static float Channel(int x, int y, int channel)
		{
			return (float)(int)rgb[(y * width + x) * 3 + channel] / 255f;
		}

		public static Color Sample(float u, float v)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(u) * (float)(width - 1);
			float num2 = (1f - Mathf.Clamp01(v)) * (float)(height - 1);
			int x0 = (int)num;
			int y0 = (int)num2;
			int x1 = Math.Min(width - 1, x0 + 1);
			int y1 = Math.Min(height - 1, y0 + 1);
			float tx = num - (float)x0;
			float ty = num2 - (float)y0;
			return new Color(Read(0), Read(1), Read(2));
			float Read(int channel)
			{
				return Mathf.Lerp(Mathf.Lerp(Channel(x0, y0, channel), Channel(x1, y0, channel), tx), Mathf.Lerp(Channel(x0, y1, channel), Channel(x1, y1, channel), tx), ty);
			}
		}
	}
	public sealed class GollumActor : EnemyAI
	{
		private sealed class Joint
		{
			internal Transform transform;

			internal Quaternion rest;
		}

		public ulong RingId;

		public int Generation;

		public int WearerSlot = -1;

		public RingEncounterState Phase;

		private readonly Dictionary<string, Joint> joints = new Dictionary<string, Joint>();

		private readonly Dictionary<long, float> recentHits = new Dictionary<long, float>();

		private readonly RaycastHit[] castHits = (RaycastHit[])(object)new RaycastHit[16];

		private GameObject visual;

		private Vector3 visualRest;

		private Vector3 lastAnimatedPosition;

		private Vector3 receivedPosition;

		private Vector3 leapStart;

		private Quaternion receivedRotation;

		private bool initialized;

		private bool havePose;

		private bool defeatSent;

		private bool registered;

		private bool bound;

		private float phaseStarted;

		private float nextPath;

		private float verticalSpeed;

		private float nextNavProbe;

		private float gait;

		private const float Radius = 0.25f;

		private const float Height = 1.2f;

		private const float LeapDuration = 0.65f;

		private int WorldMask
		{
			get
			{
				StartOfRound instance = StartOfRound.Instance;
				if (!((Object)(object)instance != (Object)null))
				{
					return LayerMask.GetMask(new string[3] { "Default", "Room", "Colliders" });
				}
				return instance.collidersAndRoomMaskAndDefault;
			}
		}

		private void Initialize()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			if (initialized)
			{
				return;
			}
			initialized = true;
			base.thisNetworkObject = ((Component)this).GetComponent<NetworkObject>();
			if ((Object)(object)base.agent == (Object)null)
			{
				base.agent = ((Component)this).GetComponent<NavMeshAgent>();
			}
			if ((Object)(object)base.agent == (Object)null)
			{
				base.agent = ((Component)this).gameObject.AddComponent<NavMeshAgent>();
			}
			((Behaviour)base.agent).enabled = false;
			base.agent.radius = 0.25f;
			base.agent.height = 1.2f;
			base.agent.baseOffset = 0f;
			base.agent.acceleration = 16f;
			base.agent.angularSpeed = 440f;
			base.agent.stoppingDistance = 1.1f;
			base.agent.updatePosition = false;
			base.agent.updateRotation = false;
			base.path1 = new NavMeshPath();
			base.agentMask = -1;
			base.removedPowerLevel = true;
			base.enemyHP = Math.Max(1, base.enemyHP);
			base.ventAnimationFinished = true;
			base.exitVentAnimationTime = 0f;
			base.stunNormalizedTimer = -1f;
			base.postStunInvincibilityTimer = -1f;
			base.currentOwnershipOnThisClient = ((!((NetworkBehaviour)this).IsServer) ? (-1) : 0);
			base.movingTowardsTargetPlayer = false;
			base.moveTowardsDestination = false;
			base.enemyBehaviourStates = (EnemyBehaviourState[])(((object)base.enemyBehaviourStates) ?? ((object)new EnemyBehaviourState[0]));
			Transform val = ((Component)this).transform.Find("GollumVisual");
			visual = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : RingVisualFactory.CreateGollum(((Component)this).transform));
			visualRest = visual.transform.localPosition;
			Transform[] componentsInChildren = visual.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				if (!joints.ContainsKey(((Object)val2).name))
				{
					joints[((Object)val2).name] = new Joint
					{
						transform = val2,
						rest = val2.localRotation
					};
				}
			}
			base.meshRenderers = ((Component)this).GetComponentsInChildren<MeshRenderer>(true);
			base.skinnedMeshRenderers = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			if (joints.TryGetValue("head", out var value))
			{
				base.eye = value.transform;
			}
			else
			{
				base.eye = ((Component)this).transform;
			}
			if ((Object)(object)base.creatureVoice == (Object)null)
			{
				base.creatureVoice = ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			base.creatureVoice.playOnAwake = false;
			base.creatureVoice.spatialBlend = 1f;
			base.creatureVoice.rolloffMode = (AudioRolloffMode)1;
			base.creatureVoice.minDistance = 1.5f;
			base.creatureVoice.maxDistance = 22f;
			if ((Object)(object)base.creatureSFX == (Object)null)
			{
				base.creatureSFX = base.creatureVoice;
			}
			lastAnimatedPosition = (receivedPosition = ((Component)this).transform.position);
			receivedRotation = ((Component)this).transform.rotation;
		}

		private void Enroll()
		{
			RoundManager instance = RoundManager.Instance;
			if (!((Object)(object)instance == (Object)null) && ((NetworkBehaviour)this).IsSpawned && !registered)
			{
				if (!instance.SpawnedEnemies.Contains((EnemyAI)(object)this))
				{
					instance.SpawnedEnemies.Add((EnemyAI)(object)this);
				}
				int numberOfEnemiesInScene = instance.numberOfEnemiesInScene;
				instance.numberOfEnemiesInScene = numberOfEnemiesInScene + 1;
				base.thisEnemyIndex = numberOfEnemiesInScene;
				registered = true;
			}
		}

		private void Unenroll()
		{
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance != (Object)null && instance.SpawnedEnemies != null)
			{
				instance.SpawnedEnemies.Remove((EnemyAI)(object)this);
			}
			registered = false;
		}

		public override void Start()
		{
			Initialize();
			Enroll();
			if (!((NetworkBehaviour)this).IsServer && ((Behaviour)base.agent).enabled)
			{
				((Behaviour)base.agent).enabled = false;
			}
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			Initialize();
			Enroll();
			base.currentOwnershipOnThisClient = ((!((NetworkBehaviour)this).IsServer) ? (-1) : 0);
			RingNet.ActorSpawned(this);
		}

		public override void OnNetworkDespawn()
		{
			Unenroll();
			if ((Object)(object)base.agent != (Object)null)
			{
				((Behaviour)base.agent).enabled = false;
			}
			RingNet.ActorDespawned(this);
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		public override void OnDestroy()
		{
			Unenroll();
			base.removedPowerLevel = true;
			base.inSpecialAnimationWithPlayer = null;
			base.inSpecialAnimation = false;
			try
			{
				((EnemyAI)this).OnDestroy();
			}
			catch (NullReferenceException) when ((Object)(object)RoundManager.Instance == (Object)null)
			{
			}
		}

		public void Bind(ulong ring, int generation, int wearer)
		{
			Initialize();
			if (!bound || RingId != ring || Generation != generation || WearerSlot != wearer)
			{
				bound = true;
				RingId = ring;
				Generation = generation;
				WearerSlot = wearer;
				base.isEnemyDead = false;
				defeatSent = false;
				recentHits.Clear();
				SetPhase(RingEncounterState.Stalking);
			}
		}

		public void SetPhase(RingEncounterState phase)
		{
			//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)
			Initialize();
			if (Phase == phase)
			{
				return;
			}
			Phase = phase;
			phaseStarted = Time.time;
			base.inSpecialAnimation = phase == RingEncounterState.Leaping || phase == RingEncounterState.Clinging;
			switch (phase)
			{
			case RingEncounterState.Leaping:
				leapStart = ((Component)this).transform.position;
				verticalSpeed = 0f;
				if (((Behaviour)base.agent).enabled)
				{
					((Behaviour)base.agent).enabled = false;
				}
				break;
			case RingEncounterState.Clinging:
				verticalSpeed = 0f;
				if (((Behaviour)base.agent).enabled)
				{
					((Behaviour)base.agent).enabled = false;
				}
				break;
			case RingEncounterState.Off:
			case RingEncounterState.Departed:
				if (((Behaviour)base.agent).enabled)
				{
					((Behaviour)base.agent).enabled = false;
				}
				break;
			default:
				nextNavProbe = 0f;
				break;
			}
		}

		public override void Update()
		{
			//IL_00b1: 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_00bd: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			Initialize();
			if (!((NetworkBehaviour)this).IsSpawned)
			{
				return;
			}
			float num = Mathf.Clamp(Time.deltaTime, 0f, 0.1f);
			base.timeSinceSpawn += num;
			if (base.stunNormalizedTimer > -1f)
			{
				base.stunNormalizedTimer -= num;
			}
			if (base.postStunInvincibilityTimer > -1f)
			{
				base.postStunInvincibilityTimer -= num;
			}
			if (!((NetworkBehaviour)this).IsServer)
			{
				if (((Behaviour)base.agent).enabled)
				{
					((Behaviour)base.agent).enabled = false;
				}
				if (havePose)
				{
					float num2 = 1f - Mathf.Exp((0f - num) * 18f);
					((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, receivedPosition, num2);
					((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, receivedRotation, num2);
				}
			}
			Animate(num);
		}

		public void ApplyPose(Vector3 position, Quaternion rotation, RingEncounterState phase)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Initialize();
			if (!((NetworkBehaviour)this).IsServer && Finite(position))
			{
				SetPhase(phase);
				if (!havePose)
				{
					((Component)this).transform.SetPositionAndRotation(position, rotation);
					havePose = true;
				}
				receivedPosition = position;
				receivedRotation = rotation;
				base.serverPosition = position;
			}
		}

		private static bool Finite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z))
			{
				return !float.IsInfinity(value.z);
			}
			return false;
		}

		private static Vector3 Chest(PlayerControllerB player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)player).transform.position + Vector3.up * 0.25f + ((Component)player).transform.forward * 0.45f;
		}

		public bool Touching(PlayerControllerB player)
		{
			//IL_0019: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player.isPlayerDead)
			{
				return false;
			}
			if (Vector3.Distance(((Component)this).transform.position, Chest(player)) <= 0.45f && Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) <= 0.85f)
			{
				return Sees(player);
			}
			return false;
		}

		public bool Sees(PlayerControllerB player)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player.isPlayerDead)
			{
				return false;
			}
			Vector3 val = ((Component)this).transform.position + Vector3.up * 0.9f;
			Vector3 val2 = ((Component)player).transform.position + Vector3.up;
			RaycastHit val3 = default(RaycastHit);
			if (!Physics.Linecast(val, val2, ref val3, WorldMask, (QueryTriggerInteraction)1))
			{
				return true;
			}
			if (!IsSelf(((RaycastHit)(ref val3)).collider))
			{
				return (Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerControllerB>() == (Object)(object)player;
			}
			return true;
		}

		public bool Grounded()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Initialize();
			if (((Behaviour)base.agent).enabled && base.agent.isOnNavMesh)
			{
				return true;
			}
			RaycastHit val = default(RaycastHit);
			if (Physics.SphereCast(((Component)this).transform.position + Vector3.up * 0.35f, 0.17f, Vector3.down, ref val, 0.5f, WorldMask, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val)).normal.y >= 0.55f;
			}
			return false;
		}

		public void HostTick(PlayerControllerB wearer, float dt)
		{
			//IL_0035: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: 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_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			Initialize();
			if (!((NetworkBehaviour)this).IsServer || !((NetworkBehaviour)this).IsSpawned || base.isEnemyDead || (Object)(object)wearer == (Object)null || wearer.isPlayerDead || !Finite(((Component)wearer).transform.position))
			{
				return;
			}
			dt = Mathf.Clamp(dt, 0f, 0.1f);
			base.targetPlayer = wearer;
			base.isOutside = !wearer.isInsideFactory;
			if (base.stunNormalizedTimer > 0f || base.stunnedIndefinitely > 0)
			{
				if (((Behaviour)base.agent).enabled && base.agent.isOnNavMesh)
				{
					base.agent.isStopped = true;
					base.agent.nextPosition = ((Component)this).transform.position;
				}
			}
			else if (Phase == RingEncounterState.Leaping)
			{
				if (((Behaviour)base.agent).enabled)
				{
					((Behaviour)base.agent).enabled = false;
				}
				float num = Mathf.Clamp01((Time.time - phaseStarted) / 0.65f);
				Vector3 val = Vector3.Lerp(leapStart, Chest(wearer), num) + Vector3.up * Mathf.Sin(num * MathF.PI) * 0.85f;
				MoveSafely(val - ((Component)this).transform.position, wearer);
				Face(((Component)wearer).transform.position - ((Component)this).transform.position, dt, 16f);
			}
			else if (Phase == RingEncounterState.Clinging)
			{
				if (((Behaviour)base.agent).enabled)
				{
					((Behaviour)base.agent).enabled = false;
				}
				MoveSafely(Vector3.ClampMagnitude(Chest(wearer) - ((Component)this).transform.position, Mathf.Max(0.05f, 16f * dt)), wearer);
				Face(-((Component)wearer).transform.forward, dt, 22f);
			}
			else
			{
				if (Phase != RingEncounterState.Stalking && Phase != RingEncounterState.Recovering)
				{
					return;
				}
				if (Phase == RingEncounterState.Recovering)
				{
					if (((Behaviour)base.agent).enabled && base.agent.isOnNavMesh)
					{
						base.agent.isStopped = true;
						base.agent.nextPosition = ((Component)this).transform.position;
					}
					ApplyGravity(dt);
					return;
				}
				EnsureNavMesh();
				float num2 = Mathf.Clamp(Plugin.CreatureSpeed.Value, 1f, 8f);
				if (((Behaviour)base.agent).enabled && base.agent.isOnNavMesh)
				{
					base.agent.speed = num2;
					base.agent.isStopped = false;
					if (Time.time >= nextPath)
					{
						nextPath = Time.time + 0.15f;
						NavMeshHit val2 = default(NavMeshHit);
						if (NavMesh.SamplePosition(((Component)wearer).transform.position, ref val2, 1.2f, base.agent.areaMask))
						{
							base.agent.SetDestination(((NavMeshHit)(ref val2)).position);
						}
						else
						{
							base.agent.isStopped = true;
						}
					}
					if (!base.agent.isStopped && !base.agent.pathPending)
					{
						Vector3 desiredVelocity = base.agent.desiredVelocity;
						if (!Finite(desiredVelocity))
						{
							base.agent.isStopped = true;
							base.agent.nextPosition = ((Component)this).transform.position;
							return;
						}
						Vector3 val3 = Vector3.ClampMagnitude(desiredVelocity * dt, num2 * dt);
						NavMeshQueryFilter val4 = default(NavMeshQueryFilter);
						((NavMeshQueryFilter)(ref val4)).agentTypeID = base.agent.agentTypeID;
						((NavMeshQueryFilter)(ref val4)).areaMask = base.agent.areaMask;
						NavMeshQueryFilter val5 = val4;
						NavMeshHit val6 = default(NavMeshHit);
						if (Finite(val3) && NavMesh.SamplePosition(((Component)this).transform.position + val3, ref val6, 0.35f, val5))
						{
							Vector3 val7 = ((NavMeshHit)(ref val6)).position - (((Component)this).transform.position + val3);
							val7.y = 0f;
							if (((Vector3)(ref val7)).sqrMagnitude <= 0.01f)
							{
								val3.y = Mathf.Clamp(((NavMeshHit)(ref val6)).position.y - ((Component)this).transform.position.y, (0f - num2) * dt, num2 * dt);
							}
						}
						MoveSafely(Vector3.ClampMagnitude(val3, num2 * dt), wearer);
						Face(desiredVelocity, dt, 10f);
					}
					base.agent.nextPosition = ((Component)this).transform.position;
					return;
				}
				Vector3 direction = ((Component)wearer).transform.position - ((Component)this).transform.position;
				direction.y = 0f;
				if (((Vector3)(ref direction)).magnitude > 1.05f)
				{
					Vector3 val8 = ((Vector3)(ref direction)).normalized * Mathf.Min(num2 * dt, ((Vector3)(ref direction)).magnitude - 1.05f);
					RaycastHit val9 = default(RaycastHit);
					if (Physics.Raycast(((Component)this).transform.position + val8 + Vector3.up * 0.5f, Vector3.down, ref val9, 1f, WorldMask, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val9)).normal.y >= 0.55f && Mathf.Abs(((RaycastHit)(ref val9)).point.y - ((Component)this).transform.position.y) <= 0.45f)
					{
						MoveSafely(new Vector3(val8.x, Mathf.Clamp(((RaycastHit)(ref val9)).point.y - ((Component)this).transform.position.y, -0.1f, 0.1f), val8.z), wearer);
					}
					Face(direction, dt, 10f);
				}
				ApplyGravity(dt);
			}
		}

		private void EnsureNavMesh()
		{
			//IL_0055: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_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_00cc: 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)
			//IL_00ed: 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)
			if (((Behaviour)base.agent).enabled && base.agent.isOnNavMesh)
			{
				return;
			}
			if (((Behaviour)base.agent).enabled)
			{
				((Behaviour)base.agent).enabled = false;
			}
			if (Time.time < nextNavProbe)
			{
				return;
			}
			nextNavProbe = Time.time + 1f;
			NavMeshQueryFilter val = default(NavMeshQueryFilter);
			((NavMeshQueryFilter)(ref val)).agentTypeID = base.agent.agentTypeID;
			((NavMeshQueryFilter)(ref val)).areaMask = base.agent.areaMask;
			NavMeshQueryFilter val2 = val;
			NavMeshHit val3 = default(NavMeshHit);
			if (NavMesh.SamplePosition(((Component)this).transform.position, ref val3, 0.45f, val2) && !Physics.Linecast(((Component)this).transform.position + Vector3.up * 0.5f, ((NavMeshHit)(ref val3)).position + Vector3.up * 0.5f, WorldMask, (QueryTriggerInteraction)1))
			{
				((Component)this).transform.position = ((NavMeshHit)(ref val3)).position;
				((Behaviour)base.agent).enabled = true;
				if (!base.agent.isOnNavMesh)
				{
					((Behaviour)base.agent).enabled = false;
				}
				else
				{
					base.agent.Warp(((NavMeshHit)(ref val3)).position);
				}
			}
		}

		private bool IsSelf(Collider collider)
		{
			if ((Object)(object)collider != (Object)null)
			{
				if (!((Object)(object)((Component)collider).transform == (Object)(object)((Component)this).transform))
				{
					return ((Component)collider).transform.IsChildOf(((Component)this).transform);
				}
				return true;
			}
			return false;
		}

		private void MoveSafely(Vector3 movement, PlayerControllerB wearer = null)
		{
			//IL_0010: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0093: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			float magnitude = ((Vector3)(ref movement)).magnitude;
			if (magnitude < 1E-05f || !Finite(movement))
			{
				return;
			}
			Vector3 val = ((Component)this).transform.position + Vector3.up * 0.25f;
			Vector3 val2 = ((Component)this).transform.position + Vector3.up * 0.95000005f;
			int num = Physics.CapsuleCastNonAlloc(val, val2, 0.25f, movement / magnitude, castHits, magnitude + 0.015f, WorldMask, (QueryTriggerInteraction)1);
			float num2 = magnitude;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val3 = castHits[i];
				if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && !IsSelf(((RaycastHit)(ref val3)).collider) && (!((Object)(object)wearer != (Object)null) || !((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<PlayerControllerB>() == (Object)(object)wearer)))
				{
					num2 = Mathf.Min(num2, Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.015f));
				}
			}
			Transform transform = ((Component)this).transform;
			transform.position += movement / magnitude * num2;
		}

		private void ApplyGravity(float dt)
		{
			//IL_0049: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Behaviour)base.agent).enabled || !base.agent.isOnNavMesh)
			{
				verticalSpeed = (Grounded() ? (-2f) : Mathf.Max(-20f, verticalSpeed - 26f * dt));
				MoveSafely(Vector3.up * verticalSpeed * dt);
			}
		}

		private void Face(Vector3 direction, float dt, float speed)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			direction.y = 0f;
			if (!(((Vector3)(ref direction)).sqrMagnitude < 0.0001f))
			{
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(direction), 1f - Mathf.Exp((0f - speed) * dt));
			}
		}

		private void Pose(string name, Vector3 angles)
		{
			//IL_0017: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (joints.TryGetValue(name, out var value))
			{
				value.transform.localRotation = value.rest * Quaternion.Euler(angles);
			}
		}

		private void Animate(float dt)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: 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_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)visual == (Object)null))
			{
				float num = ((dt > 0.0001f) ? (Vector3.Distance(((Component)this).transform.position, lastAnimatedPosition) / dt) : 0f);
				lastAnimatedPosition = ((Component)this).transform.position;
				float num2 = Mathf.Clamp01(num / 2.5f);
				gait += dt * (4f + num2 * 8f);
				float num3 = Mathf.Sin(gait);
				float num4 = Mathf.Sin(Time.time * 14f);
				bool flag = Phase == RingEncounterState.Leaping;
				bool flag2 = Phase == RingEncounterState.Clinging;
				visual.transform.localPosition = visualRest + Vector3.up * (Mathf.Abs(num3) * 0.025f * num2);
				Pose("hips", new Vector3(0f, 0f, num3 * 4f * num2));
				Pose("spine", new Vector3((float)(flag ? (-8) : (flag2 ? (-12) : 0)), num3 * 4f * num2, 0f));
				Pose("head", new Vector3(flag2 ? (-12f) : (Mathf.Sin(Time.time * 2.5f) * 3f), Mathf.Sin(Time.time * 1.8f) * 7f, flag2 ? (num4 * 4f) : 0f));
				Pose("leftArm", new Vector3(flag ? (-75f) : (flag2 ? (-115f) : (num3 * 28f * num2)), (float)(flag2 ? (-20) : 0), (float)(flag2 ? (-25) : (-8))));
				Pose("rightArm", new Vector3(flag ? (-75f) : (flag2 ? (-115f) : ((0f - num3) * 28f * num2)), (float)(flag2 ? 20 : 0), (float)(flag2 ? 25 : 8)));
				Pose("leftForearm", new Vector3(flag2 ? (-35f + num4 * 8f) : ((float)(flag ? (-15) : (-10))), 0f, 0f));
				Pose("rightForearm", new Vector3(flag2 ? (-35f - num4 * 8f) : ((float)(flag ? (-15) : (-10))), 0f, 0f));
				Pose("leftLeg", new Vector3(flag2 ? (-65f) : (flag ? (-30f) : ((0f - num3) * 32f * num2)), 0f, (float)(flag2 ? (-12) : 0)));
				Pose("rightLeg", new Vector3(flag2 ? (-65f) : (flag ? (-30f) : (num3 * 32f * num2)), 0f, (float)(flag2 ? 12 : 0)));
				Pose("leftShin", new Vector3(flag2 ? 65f : (Mathf.Max(0f, num3) * 30f * num2), 0f, 0f));
				Pose("rightShin", new Vector3(flag2 ? 65f : (Mathf.Max(0f, 0f - num3) * 30f * num2), 0f, 0f));
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			Initialize();
			if (!((NetworkBehaviour)this).IsServer || base.isEnemyDead || defeatSent || force <= 0)
			{
				return;
			}
			long key = ((long)(((Object)(object)playerWhoHit == (Object)null) ? (-1) : ((int)playerWhoHit.playerClientId)) << 32) ^ (uint)hitID;
			float now = Time.realtimeSinceStartup;
			if (recentHits.TryGetValue(key, out var value) && now - value < 0.15f)
			{
				return;
			}
			if (recentHits.Count >= 64)
			{
				long[] array = (from pair in recentHits
					where now - pair.Value >= 0.15f
					select pair.Key).ToArray();
				foreach (long key2 in array)
				{
					recentHits.Remove(key2);
				}
			}
			recentHits[key] = now;
			base.enemyHP = Math.Max(0, base.enemyHP - Mathf.Clamp(force, 1, 100));
			RingNet.CreatureHit(this);
			if (playHitSFX && (Object)(object)base.enemyType != (Object)null && (Object)(object)base.enemyType.hitBodySFX != (Object)null)
			{
				base.creatureSFX.PlayOneShot(base.enemyType.hitBodySFX);
			}
			if (base.enemyHP <= 0)
			{
				((EnemyAI)this).KillEnemy(false);
			}
		}

		public override void KillEnemy(bool destroy = false)
		{
			Initialize();
			if (base.isEnemyDead || defeatSent)
			{
				return;
			}
			if (!((NetworkBehaviour)this).IsServer)
			{
				RingNet.RequestDefeat(this);
				return;
			}
			defeatSent = true;
			base.isEnemyDead = true;
			if (((Behaviour)base.agent).enabled)
			{
				((Behaviour)base.agent).enabled = false;
			}
			RingNet.CreatureDefeated(this);
		}
	}
	internal static class NativeRingInventory
	{
		private static readonly MethodInfo Select = typeof(PlayerControllerB).GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(int),
			typeof(GrabbableObject)
		}, null);

		private static readonly MethodInfo Sync = typeof(PlayerControllerB).GetMethod("SwitchToSlotServerRpc", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(int) }, null);

		internal static bool TryDropRing(PlayerControllerB player, GrabbableObject ring)
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)ring == (Object)null || !((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || player.isPlayerDead || (Object)(object)ring.playerHeldBy != (Object)(object)player || player.isGrabbingObjectAnimation || player.inSpecialInteractAnimation || player.inTerminalMenu || player.isClimbingLadder)
			{
				return false;
			}
			int num = ((player.ItemSlots == null) ? (-1) : Array.IndexOf(player.ItemSlots, ring));
			if (num < 0 && (Object)(object)player.ItemOnlySlot == (Object)(object)ring)
			{
				num = 50;
			}
			if (num < 0)
			{
				return false;
			}
			try
			{
				if (player.currentItemSlot != num)
				{
					if (player.twoHanded || Select == null || Sync == null)
					{
						return false;
					}
					Select.Invoke(player, new object[2] { num, null });
					Sync.Invoke(player, new object[1] { num });
				}
				if (player.currentItemSlot != num || (Object)(object)player.currentlyHeldObjectServer != (Object)(object)ring || (Object)(object)ring.playerHeldBy != (Object)(object)player)
				{
					return false;
				}
				player.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Ring konnte nicht normal abgelegt werden; kein anderes Item wird fallengelassen: " + ex.Message));
				return false;
			}
		}
	}
	[BepInPlugin("tgamert.meinschatz", "Mein Schatz", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static GameObject RingPrefab;

		internal static GameObject CreaturePrefab;

		internal static ConfigEntry<float> CreatureSpeed;

		internal static ConfigEntry<int> Damage;

		internal static ConfigEntry<int> ShopPrice;

		internal static ConfigEntry<bool> ShipDelivery;

		internal static ConfigEntry<int> WearDamage;

		internal static ConfigEntry<float> WearInterval;

		internal static ConfigEntry<bool> WearCanKill;

		private Harmony harmony;

		private void Awake()
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			CreatureSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Comedy", "GollumSpeed", 3.8f, "Laufgeschwindigkeit des Ringjaegers.");
			Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Comedy", "ClingDamage", 3, "Schaden pro Klammerimpuls. Laesst mindestens 1 HP uebrig; 0 fuer reine Comedy.");
			ShopPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Ring", "ShopPrice", 10, "Ringpreis im Terminal-Shop.");
			ShipDelivery = ((BaseUnityPlugin)this).Config.Bind<bool>("Ring", "FirstRoundRing", true, "Beim ersten Einsatz einer Lobby einen kostenlosen Ring auf den Schiffsboden legen.");
			WearDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Ring", "WearDamage", 1, "Lebenspunkteverlust pro Zehrungsimpuls beim Tragen (0 bis 10). Host entscheidet.");
			WearInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Ring", "WearDamageInterval", 2f, "Sekunden zwischen Zehrungsimpulsen (0.5 bis 30). Host entscheidet.");
			WearCanKill = ((BaseUnityPlugin)this).Config.Bind<bool>("Ring", "WearDrainCanKill", true, "Die langsame Ringzehrung darf toedlich sein. False laesst mindestens 1 HP uebrig.");
			BuildPrefabs();
			((Component)this).gameObject.AddComponent<RingNet>();
			((Component)this).gameObject.AddComponent<RingWearEffects>();
			harmony = new Harmony("tgamert.meinschatz");
			harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Mein Schatz 0.2.0: Unsichtbarkeit, Lebenszehrung und Gollum registriert.");
		}

		private void OnDestroy()
		{
			RingWearEffects.ClearAll();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private static void BuildPrefabs()
		{
			//IL_0093: 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_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			RingPrefab = NetworkPrefabs.CreateNetworkPrefab("TGamerT.MeinSchatz.Ring.v1");
			RingPrefab.layer = 6;
			RingPrefab.tag = "PhysicsProp";
			GameObject val = RingVisualFactory.CreateRing(RingPrefab.transform);
			AudioSource obj = RingPrefab.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.spatialBlend = 1f;
			obj.maxDistance = 15f;
			Rigidbody val2 = RingPrefab.AddComponent<Rigidbody>();
			val2.isKinematic = true;
			val2.useGravity = false;
			BoxCollider val3 = RingPrefab.AddComponent<BoxCollider>();
			val3.size = new Vector3(0.27f, 0.12f, 0.27f);
			val3.center = new Vector3(0f, 0.04f, 0f);
			Item val4 = ScriptableObject.CreateInstance<Item>();
			((Object)val4).name = "TGamerT.MeinSchatz.Ring.Asset";
			val4.itemName = "Der Eine Ring";
			val4.spawnPrefab = RingPrefab;
			val4.weight = 1.01f;
			val4.itemSpawnsOnGround = true;
			val4.canBeGrabbedBeforeGameStart = true;
			val4.twoHanded = false;
			val4.requiresBattery = false;
			val4.automaticallySetUsingPower = false;
			val4.syncUseFunction = false;
			val4.syncInteractLRFunction = false;
			val4.holdButtonUse = false;
			val4.isScrap = false;
			val4.creditsWorth = Math.Max(0, ShopPrice.Value);
			val4.grabSFX = MetalSound();
			val4.dropSFX = val4.grabSFX;
			val4.toolTips = new string[3] { "Ring an/aus : Hauptaktion", "Abschuetteln : Zusatzaktion 1 / springen", "Ring ueberlassen : Zusatzaktion 2" };
			val4.positionOffset = new Vector3(0.04f, 0.03f, 0.08f);
			val4.rotationOffset = new Vector3(0f, 0f, 0f);
			val4.verticalOffset = 0.06f;
			CursedRingItem cursedRingItem = RingPrefab.AddComponent<CursedRingItem>();
			((GrabbableObject)cursedRingItem).itemProperties = val4;
			((GrabbableObject)cursedRingItem).grabbable = true;
			((GrabbableObject)cursedRingItem).grabbableToEnemies = true;
			((GrabbableObject)cursedRingItem).propBody = val2;
			((GrabbableObject)cursedRingItem).propColliders = (Collider[])(object)new Collider[1] { (Collider)val3 };
			((GrabbableObject)cursedRingItem).mainObjectRenderer = val.GetComponentInChildren<MeshRenderer>();
			((GrabbableObject)cursedRingItem).originalScale = Vector3.one;
			GameObject val5 = new GameObject("ScanNode")
			{
				layer = 22
			};
			val5.transform.SetParent(RingPrefab.transform, false);
			val5.transform.localPosition = Vector3.up * 0.1f;
			BoxCollider obj2 = val5.AddComponent<BoxCollider>();
			((Collider)obj2).isTrigger = true;
			obj2.size = Vector3.one * 0.3f;
			ScanNodeProperties obj3 = val5.AddComponent<ScanNodeProperties>();
			obj3.headerText = "Der Eine Ring";
			obj3.subText = "Unsichtbar. Zehrt beim Tragen an deinem Leben.";
			obj3.nodeType = 0;
			obj3.minRange = 0;
			obj3.maxRange = 20;
			obj3.requiresLineOfSight = true;
			Items.RegisterShopItem(val4, Math.Max(0, ShopPrice.Value));
			CreaturePrefab = NetworkPrefabs.CreateNetworkPrefab("TGamerT.MeinSchatz.Gollum.v1");
			CreaturePrefab.layer = 19;
			RingVisualFactory.CreateGollum(CreaturePrefab.transform);
			NavMeshAgent val6 = CreaturePrefab.AddComponent<NavMeshAgent>();
			((Behaviour)val6).enabled = false;
			val6.radius = 0.24f;
			val6.height = 1.15f;
			val6.speed = Mathf.Clamp(CreatureSpeed.Value, 1f, 8f);
			val6.acceleration = 16f;
			val6.angularSpeed = 360f;
			val6.stoppingDistance = 1.1f;
			GollumActor gollumActor = CreaturePrefab.AddComponent<GollumActor>();
			((EnemyAI)gollumActor).agent = val6;
			EnemyType val7 = ScriptableObject.CreateInstance<EnemyType>();
			val7.enemyName = "Gollum";
			val7.enemyPrefab = CreaturePrefab;
			val7.canDie = true;
			val7.PowerLevel = 0f;
			((EnemyAI)gollumActor).enemyType = val7;
			((EnemyAI)gollumActor).enemyHP = 3;
			GameObject val8 = new GameObject("GollumHitbox")
			{
				layer = 19
			};
			val8.transform.SetParent(CreaturePrefab.transform, false);
			CapsuleCollider obj4 = val8.AddComponent<CapsuleCollider>();
			((Collider)obj4).isTrigger = true;
			obj4.radius = 0.3f;
			obj4.height = 1.25f;
			obj4.center = Vector3.up * 0.65f;
			EnemyAICollisionDetect obj5 = val8.AddComponent<EnemyAICollisionDetect>();
			obj5.mainScript = (EnemyAI)(object)gollumActor;
			obj5.alwaysAllowHitting = true;
			obj5.onlyCollideWhenGrounded = false;
			Log.LogInfo((object)"Stabile Ring-/Gollum-Prefabs erstellt; beide Seiten brauchen dieselbe Modversion.");
		}

		private static AudioClip MetalSound()
		{
			float[] array = new float[4410];
			for (int i = 0; i < array.Length; i++)
			{
				float num = (float)i / 22050f;
				array[i] = Mathf.Exp((0f - num) * 30f) * (Mathf.Sin(num * 1900f * MathF.PI * 2f) * 0.12f + Mathf.Sin(num * 3713f * MathF.PI * 2f) * 0.06f);
			}
			AudioClip obj = AudioClip.Create("RingClink", array.Length, 1, 22050, false);
			obj.SetData(array, 0);
			return obj;
		}
	}
	internal static class RingAudio
	{
		private static readonly AudioClip[] clips = (AudioClip[])(object)new AudioClip[5];

		internal static void Initialize()
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
			string[] array = new string[5] { "warning", "pounce", "cling", "stolen", "hit" };
			for (int i = 0; i < array.Length; i++)
			{
				try
				{
					clips[i] = ReadWave(Path.Combine(directoryName, "audio", array[i] + ".wav"));
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Gollum-Ton nicht geladen: " + array[i] + ": " + ex.Message));
				}
			}
		}

		internal static void Play(int cue, Vector3 position)
		{
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			if (cue >= 0 && cue < clips.Length && !((Object)(object)clips[cue] == (Object)null))
			{
				GameObject val = new GameObject("GollumStimme");
				val.transform.position = position;
				AudioSource obj = val.AddComponent<AudioSource>();
				obj.spatialBlend = 1f;
				obj.minDistance = 2f;
				obj.maxDistance = 24f;
				obj.volume = 0.8f;
				obj.playOnAwake = false;
				obj.PlayOneShot(clips[cue]);
				Object.Destroy((Object)val, clips[cue].length + 0.25f);
			}
		}

		private static AudioClip ReadWave(string path)
		{
			BinaryReader reader = new BinaryReader(File.OpenRead(path));
			try
			{
				if (Four() != "RIFF")
				{
					throw new InvalidDataException("Kein RIFF");
				}
				reader.ReadInt32();
				if (Four() != "WAVE")
				{
					throw new InvalidDataException("Kein WAV");
				}
				int num = 44100;
				int num2 = 1;
				int num3 = 16;
				int num4 = 1;
				byte[] array = null;
				while (reader.BaseStream.Position + 8 <= reader.BaseStream.Length)
				{
					string text = Four();
					int num5 = reader.ReadInt32();
					long num6 = reader.BaseStream.Position + num5;
					if (num5 < 0 || num6 > reader.BaseStream.Length)
					{
						throw new InvalidDataException("WAV-Laenge");
					}
					if (text == "fmt ")
					{
						num4 = reader.ReadInt16();
						num2 = reader.ReadInt16();
						num = reader.ReadInt32();
						reader.ReadInt32();
						reader.ReadInt16();
						num3 = reader.ReadInt16();
					}
					if (text == "data")
					{
						array = reader.ReadBytes(num5);
					}
					reader.BaseStream.Position = Math.Min(reader.BaseStream.Length, num6 + (num5 & 1));
				}
				if (array == null || num4 != 1 || num3 != 16 || num2 < 1 || num2 > 2 || num < 8000 || num > 96000)
				{
					throw new InvalidDataException("PCM16 erwartet");
				}
				float[] array2 = new float[array.Length / 2];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = (float)BitConverter.ToInt16(array, i * 2) / 32768f;
				}
				AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(path), array2.Length / num2, num2, num, false);
				obj.SetData(array2, 0);
				return obj;
			}
			finally
			{
				if (reader != null)
				{
					((IDisposable)reader).Dispose();
				}
			}
			string Four()
			{
				return new string(reader.ReadChars(4));
			}
		}
	}
	public sealed class RingNet : MonoBehaviour
	{
		private sealed class Encounter
		{
			internal CursedRingItem Ring;

			internal GollumActor Actor;

			internal RingEncounterPolicy Policy;

			internal readonly RingWearDrain Drain = new RingWearDrain();

			internal int Slot;

			internal int Sequence;

			internal int Generation;

			internal bool Wearing;

			internal bool Shake;

			internal bool PendingTake;

			internal float NextSend;

			internal float RemoveAt;

			internal float TakeUntil;

			internal float NextRequest;
		}

		private const string Channel = "TGamerT.MeinSchatz.v2";

		private static RingNet instance;

		private static readonly Dictionary<ulong, CursedRingItem> rings = new Dictionary<ulong, CursedRingItem>();

		private readonly Dictionary<ulong, Encounter> encounters = new Dictionary<ulong, Encounter>();

		private readonly Dictionary<ulong, RingPacket> snapshots = new Dictionary<ulong, RingPacket>();

		private readonly Dictionary<string, int> received = new Dictionary<string, int>();

		private CustomMessagingManager messaging;

		private NetworkManager manager;

		private StartOfRound round;

		private int epoch = 1;

		private int generationSerial;

		private bool delivered;

		private bool leaving;

		private static int epochValue => instance?.epoch ?? 0;

		private static bool Server
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return false;
			}
		}

		internal static bool IsWearingRing(PlayerControllerB player)
		{
			if ((Object)(object)player != (Object)null && !player.isPlayerDead && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening)
			{
				return rings.Values.Any((CursedRingItem r) => (Object)(object)r != (Object)null && ((NetworkBehaviour)r).IsSpawned && r.Wearing && ((GrabbableObject)r).isHeld && (Object)(object)((GrabbableObject)r).playerHeldBy == (Object)(object)player);
			}
			return false;
		}

		internal static PlayerControllerB[] Wearers()
		{
			return (from r in rings.Values
				where (Object)(object)r != (Object)null && (Object)(object)((GrabbableObject)r).playerHeldBy != (Object)null && IsWearingRing(((GrabbableObject)r).playerHeldBy)
				select ((GrabbableObject)r).playerHeldBy).Distinct().ToArray();
		}

		private void Awake()
		{
			instance = this;
			RingAudio.Initialize();
		}

		internal static void RingSpawned(CursedRingItem ring)
		{
			rings[((NetworkBehaviour)ring).NetworkObjectId] = ring;
			if ((Object)(object)instance != (Object)null)
			{
				instance.ApplyCached();
			}
		}

		internal static void RingDespawned(CursedRingItem ring)
		{
			ring.Wearing = false;
			ulong networkObjectId = ((NetworkBehaviour)ring).NetworkObjectId;
			rings.Remove(networkObjectId);
			if (!((Object)(object)instance == (Object)null))
			{
				if (instance.encounters.TryGetValue(networkObjectId, out var value))
				{
					instance.RemoveActor(value);
					instance.encounters.Remove(networkObjectId);
				}
				instance.snapshots.Remove(networkObjectId);
				string suffix = ":" + networkObjectId;
				string[] array = instance.received.Keys.Where((string k) => k.EndsWith(suffix, StringComparison.Ordinal)).ToArray();
				foreach (string key in array)
				{
					instance.received.Remove(key);
				}
			}
		}

		public static void ActorSpawned(GollumActor actor)
		{
			if ((Object)(object)instance != (Object)null)
			{
				instance.ApplyCached();
			}
		}

		public static void ActorDespawned(GollumActor actor)
		{
		}

		public static void CreatureDefeated(GollumActor actor)
		{
			if (!((Object)(object)instance == (Object)null) && Server && instance.encounters.TryGetValue(actor.RingId, out var value) && !((Object)(object)value.Actor != (Object)(object)actor) && value.Policy.HasWearer)
			{
				instance.Commands(value, value.Policy.Relinquish((ulong)value.Slot, epochValue, Time.time, authoritative: true));
				instance.Broadcast(value, reliable: true);
			}
		}

		public static void CreatureHit(GollumActor actor)
		{
			if ((Object)(object)instance != (Object)null && Server && instance.encounters.TryGetValue(actor.RingId, out var value) && (Object)(object)value.Actor == (Object)(object)actor)
			{
				instance.Cue(value, 4);
			}
		}

		public static void RequestDefeat(GollumActor actor)
		{
			if (!((Object)(object)actor == (Object)null))
			{
				SendHost(new RingPacket
				{
					Kind = RingMessage.Defeat,
					Ring = actor.RingId,
					Creature = ((NetworkBehaviour)actor).NetworkObjectId,
					Generation = actor.Generation,
					Slot = LocalSlot()
				});
			}
		}

		private static int LocalSlot()
		{
			if (!((Object)(object)GameNetworkManager.Instance?.localPlayerController != (Object)null))
			{
				return -1;
			}
			return (int)GameNetworkManager.Instance.localPlayerController.playerClientId;
		}

		public static void Request(CursedRingItem ring, RingMessage kind)
		{
			if (!((Object)(object)ring == (Object)null) && ((NetworkBehaviour)ring).IsSpawned && !((Object)(object)((GrabbableObject)ring).playerHeldBy == (Object)null))
			{
				SendHost(new RingPacket
				{
					Kind = kind,
					Ring = ((NetworkBehaviour)ring).NetworkObjectId,
					Slot = (int)((GrabbableObject)ring).playerHeldBy.playerClientId
				});
			}
		}

		private unsafe static void SendHost(RingPacket packet)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)instance == (Object)null || (Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				return;
			}
			if (singleton.IsServer)
			{
				instance.Handle(singleton.LocalClientId, packet);
				return;
			}
			FastBufferWriter val = packet.Write();
			try
			{
				singleton.CustomMessagingManager.SendNamedMessage("TGamerT.MeinSchatz.v2", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private unsafe void Send(ulong client, RingPacket packet, bool reliable = true)
		{
			//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_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)manager == (Object)null || !manager.IsServer || messaging == null)
			{
				return;
			}
			if (client == manager.LocalClientId)
			{
				Handle(0uL, packet);
				return;
			}
			FastBufferWriter val = packet.Write();
			try
			{
				messaging.SendNamedMessage("TGamerT.MeinSchatz.v2", client, val, (NetworkDelivery)((!reliable) ? 1 : 3));
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private void Receive(ulong sender, FastBufferReader reader)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Handle(sender, RingPacket.Read(reader));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Ring-Nachricht verworfen: " + ex.Message));
			}
		}

		private void Update()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_025d: 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_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				if (messaging != null)
				{
					messaging.UnregisterNamedMessageHandler("TGamerT.MeinSchatz.v2");
					messaging = null;
					Clear();
				}
				return;
			}
			if (singleton.CustomMessagingManager != messaging)
			{
				if (messaging != null)
				{
					messaging.UnregisterNamedMessageHandler("TGamerT.MeinSchatz.v2");
				}
				manager = singleton;
				messaging = singleton.CustomMessagingManager;
				messaging.RegisterNamedMessageHandler("TGamerT.MeinSchatz.v2", new HandleNamedMessageDelegate(Receive));
				if (!Server)
				{
					SendHost(new RingPacket
					{
						Kind = RingMessage.Sync,
						Slot = LocalSlot()
					});
				}
			}
			if ((Object)(object)StartOfRound.Instance != (Object)(object)round)
			{
				if ((Object)(object)round != (Object)null)
				{
					((UnityEvent<PlayerControllerB>)(object)round.PlayerJumpEvent).RemoveListener((UnityAction<PlayerControllerB>)OnJump);
				}
				Clear();
				round = StartOfRound.Instance;
				epoch++;
				delivered = false;
				if ((Object)(object)round != (Object)null)
				{
					((UnityEvent<PlayerControllerB>)(object)round.PlayerJumpEvent).AddListener((UnityAction<PlayerControllerB>)OnJump);
				}
			}
			ApplyCached();
			if (!Server || (Object)(object)round == (Object)null)
			{
				return;
			}
			Encounter[] array;
			if (round.shipIsLeaving || round.firingPlayersCutsceneRunning)
			{
				if (!leaving)
				{
					leaving = true;
					array = encounters.Values.ToArray();
					foreach (Encounter encounter in array)
					{
						Commands(encounter, encounter.Policy.Relinquish((ulong)encounter.Slot, epoch, Time.time, authoritative: true));
						encounter.Wearing = false;
						Broadcast(encounter, reliable: true);
					}
				}
			}
			else
			{
				leaving = false;
			}
			if (!delivered && Plugin.ShipDelivery.Value && (Object)(object)round.localPlayerController != (Object)null && round.localPlayerController.isPlayerControlled && (Object)(object)round.middleOfShipNode != (Object)null)
			{
				delivered = true;
				Object.Instantiate<GameObject>(Plugin.RingPrefab, round.middleOfShipNode.position + Vector3.up * 0.3f, Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
				Plugin.Log.LogInfo((object)"Ein kostenloser Film-Ring liegt im Schiff. Weitere Ringe im Shop.");
			}
			array = encounters.Values.ToArray();
			foreach (Encounter e in array)
			{
				if ((Object)(object)e.Ring == (Object)null || !((NetworkBehaviour)e.Ring).IsSpawned)
				{
					RemoveActor(e);
					encounters.Remove(((Object)(object)e.Ring == (Object)null) ? encounters.FirstOrDefault((KeyValuePair<ulong, Encounter> p) => p.Value == e).Key : ((NetworkBehaviour)e.Ring).NetworkObjectId);
					continue;
				}
				PlayerControllerB val = Player(e.Slot);
				if ((Object)(object)val == (Object)null || val.isPlayerDead || !((GrabbableObject)e.Ring).isHeld || (Object)(object)((GrabbableObject)e.Ring).playerHeldBy != (Object)(object)val || leaving)
				{
					e.Wearing = false;
				}
				if (e.Policy.HasWearer)
				{
					if ((Object)(object)e.Actor != (Object)null && ((EnemyAI)e.Actor).stunNormalizedTimer > 0f)
					{
						Commands(e, e.Policy.Relinquish((ulong)e.Slot, epoch, Time.time, authoritative: true));
					}
					bool flag = ((GrabbableObject)e.Ring).isHeld && (Object)(object)((GrabbableObject)e.Ring).playerHeldBy == (Object)(object)val;
					RingEncounterFrame frame = new RingEncounterFrame
					{
						Authoritative = true,
						RoundId = epoch,
						WearerId = (ulong)e.Slot,
						Now = Time.time,
						Wearing = (e.Wearing && flag && !leaving),
						Alive = ((Object)(object)val != (Object)null && !val.isPlayerDead),
						Health = (((Object)(object)val != (Object)null) ? val.health : 0),
						Distance = (((Object)(object)e.Actor != (Object)null && (Object)(object)val != (Object)null) ? Vector3.Distance(((Component)e.Actor).transform.position, ((Component)val).transform.position) : 100f),
						Grounded = ((Object)(object)e.Actor != (Object)null && e.Actor.Grounded()),
						LineOfSight = ((Object)(object)e.Actor != (Object)null && (Object)(object)val != (Object)null && e.Actor.Sees(val)),
						TouchingWearer = ((Object)(object)e.Actor != (Object)null && (Object)(object)val != (Object)null && e.Actor.Touching(val)),
						Shake = e.Shake
					};
					e.Shake = false;
					Commands(e, e.Policy.Tick(frame));
				}
				int num = e.Drain.Tick(Server, e.Wearing && ((GrabbableObject)e.Ring).isHeld && (Object)(object)((GrabbableObject)e.Ring).playerHeldBy == (Object)(object)val && !leaving, (Object)(object)val != (Object)null && !val.isPlayerDead, e.Slot, e.Generation, Time.time, ((Object)(object)val != (Object)null) ? val.health : 0, Plugin.WearDamage.Value, Plugin.WearInterval.Value, Plugin.WearCanKill.Value);
				if (num > 0)
				{
					DrainWearer(e, num);
				}
				if ((Object)(object)e.Actor != (Object)null)
				{
					e.Actor.SetPhase(e.Policy.State);
					e.Actor.HostTick(val, Time.deltaTime);
				}
				if (e.RemoveAt > 0f && Time.time >= e.RemoveAt)
				{
					RemoveActor(e);
					e.RemoveAt = 0f;
				}
				if (e.PendingTake && ((!((GrabbableObject)e.Ring).isHeld && (Object)(object)e.Actor == (Object)null) || Time.time > e.TakeUntil))
				{
					if (!((GrabbableObject)e.Ring).isHeld)
					{
						e.PendingTake = false;
						((NetworkBehaviour)e.Ring).NetworkObject.Despawn(true);
						continue;
					}
					e.PendingTake = false;
					Plugin.Log.LogWarning((object)"Ringdiebstahl ohne bestaetigtes Ablegen abgebrochen; Item bleibt erhalten.");
				}
				e.Ring.Wearing = e.Wearing;
				if (Time.time >= e.NextSend)
				{
					e.NextSend = Time.time + 0.1f;
					Broadcast(e, reliable: false);
				}
			}
		}

		private void Handle(ulong sender, RingPacket p)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0560: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			if (p.Kind == RingMessage.Snapshot || p.Kind == RingMessage.Damage || p.Kind == RingMessage.Drop || p.Kind == RingMessage.Cue || p.Kind == RingMessage.Drain)
			{
				if (sender != 0L)
				{
					return;
				}
				if (p.Kind == RingMessage.Snapshot)
				{
					if (!snapshots.TryGetValue(p.Ring, out var value) || (p.Generation >= value.Generation && (p.Generation != value.Generation || p.Sequence > value.Sequence)))
					{
						snapshots[p.Ring] = p;
						Apply(p);
					}
					return;
				}
				string key = p.Kind.ToString() + ":" + p.Ring;
				if (received.TryGetValue(key, out var value2) && p.Sequence <= value2)
				{
					return;
				}
				received[key] = p.Sequence;
				PlayerControllerB val = Player(p.Slot);
				if (p.Kind == RingMessage.Cue)
				{
					RingAudio.Play(p.Amount, p.Position);
				}
				else
				{
					if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)GameNetworkManager.Instance?.localPlayerController || !rings.TryGetValue(p.Ring, out var value3) || (Object)(object)value3 == (Object)null || (Object)(object)((GrabbableObject)value3).playerHeldBy != (Object)(object)val || !snapshots.TryGetValue(p.Ring, out var value4) || value4.Generation != p.Generation)
					{
						return;
					}
					if (p.Kind == RingMessage.Drain)
					{
						if (value4.Wearing && value4.Slot == p.Slot && value3.Wearing && ((GrabbableObject)value3).isHeld && ((NetworkBehaviour)val).IsOwner)
						{
							DamageDrainLocal(val, p.Amount, p.State == 1);
						}
					}
					else if (p.Kind == RingMessage.Damage)
					{
						DamageLocal(val, p.Amount);
					}
					else
					{
						DropLocal(val, p.Ring);
					}
				}
			}
			else
			{
				if (!Server)
				{
					return;
				}
				if (p.Kind == RingMessage.Sync)
				{
					foreach (Encounter value8 in encounters.Values)
					{
						Send(sender, Packet(value8, RingMessage.Snapshot));
					}
					return;
				}
				if (!rings.TryGetValue(p.Ring, out var value5) || (Object)(object)value5 == (Object)null || !((NetworkBehaviour)value5).IsSpawned)
				{
					return;
				}
				if (p.Kind == RingMessage.Defeat)
				{
					PlayerControllerB val2 = Player(p.Slot);
					if (encounters.TryGetValue(p.Ring, out var value6) && !((Object)(object)value6.Actor == (Object)null) && p.Creature == ((NetworkBehaviour)value6.Actor).NetworkObjectId && p.Generation == value6.Actor.Generation && !((Object)(object)val2 == (Object)null) && !val2.isPlayerDead && val2.actualClientId == sender && !(Vector3.Distance(((Component)val2).transform.position, ((Component)value6.Actor).transform.position) > 65f))
					{
						CreatureDefeated(value6.Actor);
					}
					return;
				}
				PlayerControllerB playerHeldBy = ((GrabbableObject)value5).playerHeldBy;
				if ((Object)(object)playerHeldBy == (Object)null || playerHeldBy.isPlayerDead || !((GrabbableObject)value5).isHeld || ((NetworkBehaviour)value5).OwnerClientId != sender || (int)playerHeldBy.playerClientId != p.Slot)
				{
					return;
				}
				if (!encounters.TryGetValue(p.Ring, out var value7))
				{
					value7 = new Encounter
					{
						Ring = value5,
						Slot = p.Slot,
						Policy = new RingEncounterPolicy(new RingEncounterSettings
						{
							DamagePerTick = Mathf.Clamp(Plugin.Damage.Value, 0, 25)
						})
					};
					encounters[p.Ring] = value7;
				}
				if (Time.time < value7.NextRequest)
				{
					return;
				}
				value7.NextRequest = Time.time + ((p.Kind == RingMessage.Shake) ? 0.5f : 0.35f);
				if (p.Kind == RingMessage.Toggle)
				{
					if (!value7.Wearing)
					{
						if (leaving || encounters.Values.Count((Encounter x) => x.Wearing) >= 3 || SlotAlreadyWearing(p.Slot))
						{
							return;
						}
						value7.Slot = p.Slot;
						value7.Wearing = true;
						value7.RemoveAt = 0f;
						value7.Generation = ++generationSerial;
						Commands(value7, value7.Policy.BeginWear((ulong)value7.Slot, epoch, Time.time, authoritative: true));
					}
					else
					{
						Commands(value7, value7.Policy.Relinquish((ulong)value7.Slot, epoch, Time.time, authoritative: true));
						value7.Wearing = false;
					}
				}
				else if (p.Kind == RingMessage.Shake && value7.Wearing)
				{
					value7.Shake = true;
				}
				else if (p.Kind == RingMessage.Surrender && value7.Wearing && (Object)(object)value7.Actor != (Object)null && value7.Actor.Sees(playerHeldBy) && Vector3.Distance(((Component)value7.Actor).transform.position, ((Component)playerHeldBy).transform.position) < 4f)
				{
					Commands(value7, value7.Policy.Relinquish((ulong)value7.Slot, epoch, Time.time, authoritative: true, offerRing: true));
					value7.Wearing = false;
				}
				value5.Wearing = value7.Wearing;
				Broadcast(value7, reliable: true);
			}
		}

		private RingPacket Packet(Encounter e, RingMessage kind)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			return new RingPacket
			{
				Kind = kind,
				Ring = ((NetworkBehaviour)e.Ring).NetworkObjectId,
				Creature = (((Object)(object)e.Actor != (Object)null && ((NetworkBehaviour)e.Actor).IsSpawned) ? ((NetworkBehaviour)e.Actor).NetworkObjectId : 0),
				Slot = e.Slot,
				Generation = e.Generation,
				State = (int)e.Policy.State,
				Amount = (((Object)(object)e.Actor != (Object)null && ((EnemyAI)e.Actor).isEnemyDead) ? 1 : 0),
				Wearing = e.Wearing,
				Sequence = ++e.Sequence,
				Position = (((Object)(object)e.Actor != (Object)null) ? ((Component)e.Actor).transform.position : ((Component)e.Ring).transform.position),
				Rotation = (((Object)(object)e.Actor != (Object)null) ? ((Component)e.Actor).transform.rotation : Quaternion.identity)
			};
		}

		private bool SlotAlreadyWearing(int slot)
		{
			foreach (Encounter value in encounters.Values)
			{
				if (value.Wearing && value.Slot == slot)
				{
					return true;
				}
			}
			return false;
		}

		private void Broadcast(Encounter e, bool reliable)
		{
			RingPacket packet = Packet(e, RingMessage.Snapshot);
			foreach (ulong connectedClientsId in manager.ConnectedClientsIds)
			{
				Send(connectedClientsId, packet, reliable);
			}
		}

		private void Commands(Encounter e, RingEncounterCommand[] commands)
		{
			for (int i = 0; i < commands.Length; i++)
			{
				RingEncounterCommand ringEncounterCommand = commands[i];
				switch (ringEncounterCommand.Kind)
				{
				case RingEncounterCommandKind.Warning:
					Cue(e, 0);
					break;
				case RingEncounterCommandKind.Spawn:
					if (!SpawnCreature(e))
					{
						Commands(e, e.Policy.Relinquish((ulong)e.Slot, epoch, Time.time, authoritative: true));
					}
					break;
				case RingEncounterCommandKind.Pounce:
					Cue(e, 1);
					break;
				case RingEncounterCommandKind.Cling:
					Cue(e, 2);
					break;
				case RingEncounterCommandKind.Release:
					if (ringEncounterCommand.Reason == RingEncounterReason.ShakenOff)
					{
						Cue(e, 4);
					}
					break;
				case RingEncounterCommandKind.Damage:
					DamageWearer(e, ringEncounterCommand.Amount);
					break;
				case RingEncounterCommandKind.TakeRing:
				{
					e.PendingTake = true;
					e.TakeUntil = Time.time + 2f;
					e.Wearing = false;
					Cue(e, 3);
					PlayerControllerB val = Player(e.Slot);
					if ((Object)(object)val != (Object)null)
					{
						if (Intern(val) != null)
						{
							DropNpc(val, e.Ring);
							break;
						}
						RingPacket packet = Packet(e, RingMessage.Drop);
						Send(val.actualClientId, packet);
					}
					break;
				}
				case RingEncounterCommandKind.Despawn:
					e.RemoveAt = Time.time + 2f;
					break;
				}
			}
		}

		private bool SpawnCreature(Encounter e)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_0092: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = Player(e.Slot);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Vector3 val2 = ((Component)val).transform.position;
			bool flag = false;
			NavMeshHit val4 = default(NavMeshHit);
			RaycastHit val6 = default(RaycastHit);
			for (int i = 0; i < 10; i++)
			{
				float num = (float)i * 137.5f * (MathF.PI / 180f);
				Vector3 val3 = ((Component)val).transform.position + new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)) * (float)(val.isInHangarShipRoom ? 3 : 7);
				if (NavMesh.SamplePosition(val3, ref val4, 2.5f, -1))
				{
					NavMeshPath val5 = new NavMeshPath();
					if (NavMesh.CalculatePath(((Component)val).transform.position, ((NavMeshHit)(ref val4)).position, -1, val5) && (int)val5.status == 0)
					{
						val2 = ((NavMeshHit)(ref val4)).position;
						flag = true;
						break;
					}
				}
				if (Physics.Raycast(val3 + Vector3.up * 2f, Vector3.down, ref val6, 5f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) && !Physics.Linecast(((Component)val.gameplayCamera).transform.position, ((RaycastHit)(ref val6)).point + Vector3.up, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
				{
					val2 = ((RaycastHit)(ref val6)).point;
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				Plugin.Log.LogWarning((object)"Hier kein erreichbarer Boden fuer Gollum. Ring kann erneut probiert werden.");
				return false;
			}
			RemoveActor(e);
			GameObject val7 = Object.Instantiate<GameObject>(Plugin.CreaturePrefab, val2, Quaternion.identity);
			e.Actor = val7.GetComponent<GollumActor>();
			e.Actor.Bind(((NetworkBehaviour)e.Ring).NetworkObjectId, e.Generation, e.Slot);
			((EnemyAI)e.Actor).isOutside = !val.isInsideFactory;
			val7.GetComponent<NetworkObject>().Spawn(false);
			return true;
		}

		private void Cue(Encounter e, int cue)
		{
			RingPacket packet = Packet(e, RingMessage.Cue);
			packet.Amount = cue;
			foreach (ulong connectedClientsId in manager.ConnectedClientsIds)
			{
				Send(connectedClientsId, packet);
			}
		}

		private void DamageWearer(Encounter e, int amount)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = Player(e.Slot);
			if ((Object)(object)val == (Object)null || val.isPlayerDead || (Object)(object)e.Actor == (Object)null || !e.Actor.Touching(val))
			{
				return;
			}
			amount = Math.Min(Math.Max(0, amount), Math.Max(0, val.health - 1));
			if (amount != 0)
			{
				if (Intern(val) != null)
				{
					val.DamagePlayer(amount, true, true, (CauseOfDeath)6, 0, false, default(Vector3));
					return;
				}
				RingPacket packet = Packet(e, RingMessage.Damage);
				packet.Amount = amount;
				Send(val.actualClientId, packet);
			}
		}

		private static void DamageLocal(PlayerControllerB player, int amount)
		{
			//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)
			if (!player.isPlayerDead)
			{
				amount = Math.Min(Math.Max(0, amount), Math.Max(0, player.health - 1));
				if (amount > 0)
				{
					player.DamagePlayer(amount, true, true, (CauseOfDeath)6, 0, false, default(Vector3));
				}
			}
		}

		private void DrainWearer(Encounter e, int amount)
		{
			PlayerControllerB val = Player(e.Slot);
			if (Server && e.Wearing && !((Object)(object)val == (Object)null) && !val.isPlayerDead && ((GrabbableObject)e.Ring).isHeld && !((Object)(object)((GrabbableObject)e.Ring).playerHeldBy != (Object)(object)val))
			{
				if (Intern(val) != null)
				{
					DamageDrainLocal(val, amount, Plugin.WearCanKill.Value);
					return;
				}
				RingPacket packet = Packet(e, RingMessage.Drain);
				packet.Amount = amount;
				packet.State = (Plugin.WearCanKill.Value ? 1 : 0);
				Send(val.actualClientId, packet);
			}
		}

		private static void DamageDrainLocal(PlayerControllerB player, int amount, bool fatal)
		{
			//IL_0048: 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)
			if (!((Object)(object)player == (Object)null) && !player.isPlayerDead && IsWearingRing(player))
			{
				amount = Math.Min(Mathf.Clamp(amount, 0, 10), Math.Max(0, player.health - ((!fatal) ? 1 : 0)));
				if (amount > 0)
				{
					player.DamagePlayer(amount, false, true, (CauseOfDeath)0, 0, false, default(Vector3));
				}
			}
		}

		private void ApplyCached()
		{
			RingPacket[] array = snapshots.Values.ToArray();
			foreach (RingPacket p in array)
			{
				Apply(p);
			}
		}

		private void Apply(RingPacket p)
		{
			//IL_00f5: 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)
			if (rings.TryGetValue(p.Ring, out var value) && (Object)(object)value != (Object)null)
			{
				value.Wearing = p.Wearing;
			}
			if (Server || p.Creature == 0L || (Object)(object)manager == (Object)null || !manager.SpawnManager.SpawnedObjects.TryGetValue(p.Creature, out var value2))
			{
				return;
			}
			GollumActor component = ((Component)value2).GetComponent<GollumActor>();
			if ((Object)(object)component != (Object)null)
			{
				if (component.RingId != p.Ring || component.Generation != p.Generation || component.WearerSlot != p.Slot)
				{
					component.Bind(p.Ring, p.Generation, p.Slot);
				}
				((EnemyAI)component).isEnemyDead = (p.Amount & 1) != 0;
				PlayerControllerB val = Player(p.Slot);
				if ((Object)(object)val != (Object)null)
				{
					((EnemyAI)component).isOutside = !val.isInsideFactory;
				}
				component.ApplyPose(p.Position, p.Rotation, (RingEncounterState)p.State);
			}
		}

		private static PlayerControllerB Player(int slot)
		{
			if (StartOfRound.Instance?.allPlayerScripts == null || slot < 0 || slot >= StartOfRound.Instance.allPlayerScripts.Length)
			{
				return null;
			}
			return StartOfRound.Instance.allPlayerScripts[slot];
		}

		private static object Intern(PlayerControllerB player)
		{
			try
			{
				object obj = Type.GetType("LethalInternship.SharedAbstractions.ManagerProviders.InternManagerProvider, LethalInternship.SharedAbstractions", throwOnError: false)?.GetProperty("Instance")?.GetValue(null);
				return obj?.GetType().GetMethod("GetInternAI", new Type[1] { typeof(int) })?.Invoke(obj, new object[1] { (int)player.playerClientId });
			}
			catch
			{
				return null;
			}
		}

		private static void DropNpc(PlayerControllerB player, CursedRingItem ring)
		{
			object obj = Intern(player);
			obj?.GetType().GetMethod("DropItem", new Type[1] { typeof(GrabbableObject) })?.Invoke(obj, new object[1] { ring });
		}

		private static void DropLocal(PlayerControllerB player, ulong ringId)
		{
			if (rings.TryGetValue(ringId, out var value) && !((Object)(object)value == (Object)null) && !((Object)(object)((GrabbableObject)value).playerHeldBy != (Object)(object)player))
			{
				NativeRingInventory.TryDropRing(player, (GrabbableObject)(object)value);
			}
		}

		private void RemoveActor(Encounter e)
		{
			if ((Object)(object)e.Actor != (Object)null && ((NetworkBehaviour)e.Actor).IsSpawned && Server && NetworkManager.Singleton.IsListening)
			{
				((NetworkBehaviour)e.Actor).NetworkObject.Despawn(true);
			}
			e.Actor = null;
		}

		private void Clear()
		{
			foreach (CursedRingItem value in rings.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					value.Wearing = false;
				}
			}
			RingWearEffects.ClearAll();
			Encounter[] array = encounters.Values.ToArray();
			foreach (Encounter e in array)
			{
				RemoveActor(e);
			}
			encounters.Clear();
			snapshots.Clear();
			received.Clear();
			leaving = false;
		}

		private void OnJump(PlayerControllerB player)
		{
			CursedRingItem[] array = rings.Values.ToArray();
			foreach (CursedRingItem cursedRingItem in array)
			{
				if ((Object)(object)cursedRingItem != (Object)null && ((NetworkBehaviour)cursedRingItem).IsOwner && cursedRingItem.Wearing && (Object)(object)((GrabbableObject)cursedRingItem).playerHeldBy == (Object)(object)player)
				{
					Request(cursedRingItem, RingMessage.Shake);
				}
			}
		}

		private void OnDestroy()
		{
			Clear();
			if ((Object)(object)round != (Object)null)
			{
				((UnityEvent<PlayerControllerB>)(object)round.PlayerJumpEvent).RemoveListener((UnityAction<PlayerControllerB>)OnJump);
			}
			if (messaging != null)
			{
				messaging.UnregisterNamedMessageHandler("TGamerT.MeinSchatz.v2");
			}
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}
	}
	public enum RingMessage : byte
	{
		Toggle = 1,
		Shake,
		Surrender,
		Snapshot,
		Damage,
		Drop,
		Defeat,
		Sync,
		Cue,
		Drain
	}
	internal struct RingPacket
	{
		internal RingMessage Kind;

		internal ulong Ring;

		internal ulong Creature;

		internal int Generation;

		internal int Slot;

		internal int State;

		internal int Amount;

		internal int Sequence;

		internal bool Wearing;

		internal Vector3 Position;

		internal Quaternion Rotation;

		internal FastBufferWriter Write()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0045: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter result = default(FastBufferWriter);
			((FastBufferWriter)(ref result))..ctor(128, (Allocator)2, -1);
			byte b = 2;
			byte kind = (byte)Kind;
			((FastBufferWriter)(ref result)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<byte>(ref kind, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<ulong>(ref Ring, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<ulong>(ref Creature, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Generation, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Slot, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref State, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Amount, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<int>(ref Sequence, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe<bool>(ref Wearing, default(ForPrimitives));
			((FastBufferWriter)(ref result)).WriteValueSafe(ref Position);
			((FastBufferWriter)(ref result)).WriteValueSafe(ref Rotation);
			return result;
		}

		internal static RingPacket Read(FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0088: 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_009f: 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_00b6: 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_00cd: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0167: 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_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			byte b = default(byte);
			((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
			byte b2 = default(byte);
			((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref b2, default(ForPrimitives));
			if (b != 2 || b2 < 1 || b2 > 10)
			{
				throw new ArgumentException("Unbekanntes Ringprotokoll");
			}
			RingPacket result = new RingPacket
			{
				Kind = (RingMessage)b2
			};
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref result.Ring, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref result.Creature, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref result.Generation, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref result.Slot, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref result.State, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref result.Amount, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref result.Sequence, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref result.Wearing, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe(ref result.Position);
			((FastBufferReader)(ref r)).ReadValueSafe(ref result.Rotation);
			if (result.Slot < -1 || result.Slot > 255 || result.State < 0 || result.State > 6 || !Finite(result.Position.x) || !Finite(result.Position.y) || !Finite(result.Position.z) || !Finite(result.Rotation.x) || !Finite(result.Rotation.y) || !Finite(result.Rotation.z) || !Finite(result.Rotation.w))
			{
				throw new ArgumentException("Ungueltiger Ringzustand");
			}
			return result;
		}

		private static bool Finite(float v)
		{
			if (!float.IsNaN(v) && !float.IsInfinity(v))
			{
				return Math.Abs(v) < 1000000f;
			}
			return false;
		}
	}
	internal static class RingSight
	{
		[ThreadStatic]
		internal static int Depth;

		internal static bool HiddenFrom(EnemyAI enemy, PlayerControllerB player)
		{
			if (!(enemy is GollumActor))
			{
				return RingWearEffects.IsInvisible(player);
			}
			return false;
		}

		internal static IEnumerable<MethodBase> Queries()
		{
			string[] names = new string[4] { "GetAllPlayersInLineOfSight", "GetAllPlayersInLineOfSightNonAlloc", "CheckLOSForTarget", "CheckLOSForClosestPlayer" };
			MethodInfo[] methods = typeof(EnemyAI).GetMethods();
			foreach (MethodInfo methodInfo in methods)
			{
				if (names.Contains(methodInfo.Name))
				{
					yield return methodInfo;
				}
			}
			Assembly[] assembli