Decompiled source of OldCamera v1.1.0

Mods/OldCamera.dll

Decompiled 5 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2Cpp;
using Il2CppCinemachine;
using Il2CppFemur;
using Il2CppGB.Core;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using OldCamera;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(OldCameraMod), "OldCamera", "1.1.0", "Zooks", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("OldCamera")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("mod for Gang Beasts")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OldCamera")]
[assembly: AssemblyTitle("OldCamera")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace OldCamera
{
	public sealed class OldCameraRenderDriver : MonoBehaviour
	{
		public OldCameraRenderDriver(IntPtr pointer)
			: base(pointer)
		{
		}

		public void OnDisable()
		{
			OldCameraMod.Instance?.AfterRender(this);
		}
	}
	public class OldCameraMod : MelonMod
	{
		private struct StateMessage
		{
			public Actor Actor;

			public ActorState State;

			public string Source;
		}

		private sealed class Beast
		{
			public int Key;

			public Actor Actor;

			public Transform Root;

			public Transform Target;

			public bool IsAI;

			public bool Known;

			public bool Dead;

			public bool HasPosition;

			public Vector3 Position;

			public float NextTargetRefresh;

			public float LastEventTime = -100f;

			public float AliveSince = -1f;
		}

		private sealed class RenderState
		{
			public Camera Camera;

			public Transform Transform;

			public OldCameraRenderDriver Driver;

			public bool Applied;

			public Vector3 BasePosition;

			public Vector3 WrittenPosition;

			public bool ReceivedBrainUpdate;

			public bool Warned;

			public float AttachedAt;

			public int LoggedTransition = -1;

			public bool HasDisplayedPosition;

			public Vector3 DisplayedPosition;

			public int LastDisplayedFrame = -1;

			public bool SmoothingMovement;

			public int LastSmoothingFrame = -1;
		}

		private sealed class ComposerState
		{
			public GangBeastsGroupComposer Composer;

			public float Original;

			public float Applied;
		}

		internal static OldCameraMod Instance;

		private MelonPreferences_Category _category;

		private MelonPreferences_Entry<bool> _pTrackAI;

		private MelonPreferences_Entry<bool> _pDiagnostics;

		private MelonPreferences_Entry<float> _pDipTime;

		private MelonPreferences_Entry<float> _pReturnTime;

		private MelonPreferences_Entry<float> _pDepth;

		private MelonPreferences_Entry<float> _pSideReach;

		private MelonPreferences_Entry<float> _pStrength;

		private MelonPreferences_Entry<float> _pRoughness;

		private MelonPreferences_Entry<float> _pMaxOffset;

		private MelonPreferences_Entry<float> _pDamping;

		private bool _trackAI = true;

		private bool _diagnostics = true;

		private float _dipTime = 0.85f;

		private float _returnTime = 2.4f;

		private float _depth = -1.25f;

		private float _sideReach = 0.65f;

		private float _strength = 1.5f;

		private float _maxOffset = 3f;

		private float _roughness = 0.022f;

		private float _damping = 4.5f;

		private readonly ConcurrentQueue<StateMessage> _stateQueue = new ConcurrentQueue<StateMessage>();

		private ActorStateHandler _clientDelegate;

		private ActorStateHandler _serverDelegate;

		private bool _clientSubscribed;

		private bool _serverSubscribed;

		private volatile bool _acceptEvents;

		private readonly Dictionary<int, Beast> _beasts = new Dictionary<int, Beast>();

		private readonly List<int> _removeKeys = new List<int>();

		private readonly List<int> _pendingDeaths = new List<int>();

		private int _livingCount;

		private Vector3 _centroid;

		private CMTargetGroupHandler _handler;

		private CMTargetGroupPool _pool;

		private bool _aiCached;

		private bool _originalTrackAI;

		private float _originalAIWeight;

		private float _originalAIRadius;

		private CinemachineTargetGroup _aiGroup;

		private readonly Dictionary<int, Transform> _addedAI = new Dictionary<int, Transform>();

		private readonly Dictionary<IntPtr, RenderState> _renderers = new Dictionary<IntPtr, RenderState>();

		private readonly HashSet<IntPtr> _knownCameras = new HashSet<IntPtr>();

		private readonly List<IntPtr> _removeRenderers = new List<IntPtr>();

		private MethodInfo _brainLateUpdateMethod;

		private bool _brainPatchInstalled;

		private readonly List<ComposerState> _composers = new List<ComposerState>();

		private readonly HashSet<IntPtr> _knownComposers = new HashSet<IntPtr>();

		private bool _moving;

		private int _transitionId;

		private int _startFrame = -1;

		private int _advancedFrame = -1;

		private float _dipProgress;

		private float _returnProgress;

		private Vector3 _startOffset;

		private Vector3 _peakOffset;

		private Vector3 _offset;

		private int _seed;

		private bool _gameplay;

		private bool _insideTick;

		private bool _insideRender;

		private float _nextDiscovery;

		private float _nextCameraScan;

		private float _nextSettings;

		private float _nextAI;

		private float _nextStatus;

		private float _lastError = -100f;

		private int _clientEvents;

		private int _serverEvents;

		private int _detectedDeaths;

		public override void OnInitializeMelon()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			InitializePreferences();
			ClassInjector.RegisterTypeInIl2Cpp<OldCameraRenderDriver>();
			_clientDelegate = DelegateSupport.ConvertDelegate<ActorStateHandler>((Delegate)new Action<Actor, int, ActorState>(OnClientState));
			_serverDelegate = DelegateSupport.ConvertDelegate<ActorStateHandler>((Delegate)new Action<Actor, int, ActorState>(OnServerState));
			Scene activeScene = SceneManager.GetActiveScene();
			_gameplay = IsGameplayScene(((Scene)(ref activeScene)).name);
			_acceptEvents = _gameplay;
			if (_gameplay)
			{
				SubscribeStateEvents();
			}
			InstallBrainPatch();
			((MelonBase)this).LoggerInstance.Msg("OldCamera 1.2.1 initialized. Online death detection and final-position smoothing. Patch installed=" + _brainPatchInstalled + " strength=" + _strength + " maximumOffset=" + _maxOffset);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			_gameplay = false;
			Cleanup();
			_gameplay = IsGameplayScene(sceneName);
			_acceptEvents = _gameplay;
			if (_gameplay)
			{
				SubscribeStateEvents();
			}
		}

		public override void OnDeinitializeMelon()
		{
			_gameplay = false;
			_acceptEvents = false;
			RemoveBrainPatch();
			Cleanup();
			Instance = null;
		}

		public override void OnUpdate()
		{
			foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
			{
				RestorePosition(renderer.Value);
			}
			if (_gameplay)
			{
				Tick();
			}
		}

		public override void OnLateUpdate()
		{
			if (_gameplay)
			{
				Tick();
			}
		}

		private static bool IsGameplayScene(string name)
		{
			if (!string.IsNullOrEmpty(name))
			{
				return name != Global.MENU_SCENE_NAME;
			}
			return false;
		}

		private void InstallBrainPatch()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			if (_brainPatchInstalled)
			{
				return;
			}
			try
			{
				_brainLateUpdateMethod = AccessTools.Method(typeof(CinemachineBrain), "LateUpdate", Type.EmptyTypes, (Type[])null);
				if (_brainLateUpdateMethod == null)
				{
					((MelonBase)this).LoggerInstance.Error("CAMERA PATCH FAILED: CinemachineBrain.LateUpdate was not found.");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(OldCameraMod), "AfterCinemachineLateUpdate", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					((MelonBase)this).LoggerInstance.Error("CAMERA PATCH FAILED: postfix method was not found.");
					return;
				}
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)_brainLateUpdateMethod, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_brainPatchInstalled = true;
				((MelonBase)this).LoggerInstance.Msg("CAMERA PATCH INSTALLED: CinemachineBrain.LateUpdate");
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("CAMERA PATCH FAILED: " + ex);
			}
		}

		private void RemoveBrainPatch()
		{
			if (_brainPatchInstalled && !(_brainLateUpdateMethod == null))
			{
				try
				{
					((MelonBase)this).HarmonyInstance.Unpatch((MethodBase)_brainLateUpdateMethod, (HarmonyPatchType)2, ((MelonBase)this).HarmonyInstance.Id);
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Error("Camera patch removal failed: " + ex);
				}
				_brainPatchInstalled = false;
				_brainLateUpdateMethod = null;
			}
		}

		private static void AfterCinemachineLateUpdate(CinemachineBrain __instance)
		{
			OldCameraMod instance = Instance;
			if (instance == null)
			{
				return;
			}
			try
			{
				instance.ApplyAfterCinemachine(__instance);
			}
			catch (Exception exception)
			{
				instance.Report("Cinemachine postfix", exception);
			}
		}

		private void ApplyAfterCinemachine(CinemachineBrain brain)
		{
			//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_00c4: 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_00ca: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			if (!_gameplay || _insideRender || (Object)(object)brain == (Object)null || !((Behaviour)brain).enabled)
			{
				return;
			}
			Camera component = ((Component)brain).GetComponent<Camera>();
			if ((Object)(object)component == (Object)null || !((Behaviour)component).enabled || !((Component)component).gameObject.activeInHierarchy)
			{
				return;
			}
			_insideRender = true;
			RenderState renderState = null;
			try
			{
				Tick();
				renderState = FindRenderState(component);
				if (renderState == null)
				{
					Attach(component);
					renderState = FindRenderState(component);
				}
				if (renderState == null || (Object)(object)renderState.Transform == (Object)null)
				{
					return;
				}
				if (!renderState.ReceivedBrainUpdate)
				{
					renderState.ReceivedBrainUpdate = true;
					((MelonBase)this).LoggerInstance.Msg("CINEMACHINE POSTFIX RUNNING: " + ((Object)component).name);
				}
				RestorePosition(renderState);
				Vector3 position = renderState.Transform.position;
				Vector3 val = DisplayOffset();
				if (!Finite(position) || !Finite(val))
				{
					return;
				}
				Vector3 val2 = position + val;
				if (!Finite(val2))
				{
					return;
				}
				int frameCount = Time.frameCount;
				bool flag = renderState.HasDisplayedPosition && frameCount >= renderState.LastDisplayedFrame && frameCount - renderState.LastDisplayedFrame <= 2;
				if (!flag)
				{
					renderState.DisplayedPosition = val2;
					renderState.HasDisplayedPosition = true;
					renderState.SmoothingMovement = false;
					renderState.LastSmoothingFrame = -1;
				}
				if (_moving && flag)
				{
					renderState.SmoothingMovement = true;
				}
				Vector3 val3 = val2;
				if (renderState.SmoothingMovement)
				{
					if (renderState.LastSmoothingFrame != frameCount)
					{
						renderState.LastSmoothingFrame = frameCount;
						float num = Mathf.Max(0f, Time.unscaledDeltaTime);
						float num2 = 1f - Mathf.Exp((0f - num) / 0.12f);
						renderState.DisplayedPosition = Vector3.Lerp(renderState.DisplayedPosition, val2, num2);
					}
					val3 = renderState.DisplayedPosition;
					if (!_moving)
					{
						Vector3 val4 = val3 - val2;
						if (((Vector3)(ref val4)).sqrMagnitude < 1E-06f)
						{
							renderState.SmoothingMovement = false;
							val3 = val2;
						}
					}
				}
				if (!Finite(val3))
				{
					return;
				}
				renderState.DisplayedPosition = val3;
				renderState.HasDisplayedPosition = true;
				renderState.LastDisplayedFrame = frameCount;
				Vector3 val5 = val3 - position;
				if (!(((Vector3)(ref val5)).sqrMagnitude < 1E-08f))
				{
					renderState.BasePosition = position;
					renderState.WrittenPosition = val3;
					renderState.Transform.position = val3;
					renderState.Applied = true;
					if (_diagnostics && _moving && renderState.LoggedTransition != _transitionId)
					{
						renderState.LoggedTransition = _transitionId;
						((MelonBase)this).LoggerInstance.Msg("SMOOTH DEATH MOVEMENT: #" + _transitionId + " camera=" + ((Object)component).name + " strength=" + _strength);
					}
				}
			}
			catch
			{
				if (renderState != null)
				{
					RestorePosition(renderState);
				}
				throw;
			}
			finally
			{
				_insideRender = false;
			}
		}

		private void OnClientState(Actor actor, int connectionId, ActorState state)
		{
			//IL_0023: 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)
			if (_acceptEvents)
			{
				_stateQueue.Enqueue(new StateMessage
				{
					Actor = actor,
					State = state,
					Source = "client event"
				});
			}
		}

		private void OnServerState(Actor actor, int connectionId, ActorState state)
		{
			//IL_0023: 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)
			if (_acceptEvents)
			{
				_stateQueue.Enqueue(new StateMessage
				{
					Actor = actor,
					State = state,
					Source = "server event"
				});
			}
		}

		private void SubscribeStateEvents()
		{
			try
			{
				Actor.OnActorStateChangedClient -= _clientDelegate;
				Actor.OnActorStateChangedClient += _clientDelegate;
				_clientSubscribed = true;
			}
			catch (Exception exception)
			{
				_clientSubscribed = false;
				Report("subscribe client state event", exception);
			}
			try
			{
				Actor.OnActorStateChangedServer -= _serverDelegate;
				Actor.OnActorStateChangedServer += _serverDelegate;
				_serverSubscribed = true;
			}
			catch (Exception exception2)
			{
				_serverSubscribed = false;
				Report("subscribe server state event", exception2);
			}
		}

		private void UnsubscribeStateEvents()
		{
			try
			{
				if ((Delegate)(object)_clientDelegate != (Delegate)null)
				{
					Actor.OnActorStateChangedClient -= _clientDelegate;
				}
			}
			catch
			{
			}
			try
			{
				if ((Delegate)(object)_serverDelegate != (Delegate)null)
				{
					Actor.OnActorStateChangedServer -= _serverDelegate;
				}
			}
			catch
			{
			}
			_clientSubscribed = false;
			_serverSubscribed = false;
		}

		private void ProcessStateEvents(float now)
		{
			//IL_0068: 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)
			StateMessage result;
			while (_stateQueue.TryDequeue(out result))
			{
				if ((Object)(object)result.Actor == (Object)null)
				{
					continue;
				}
				Beast beast = Register(result.Actor);
				if (beast != null)
				{
					if (result.Source == "client event")
					{
						_clientEvents++;
					}
					else
					{
						_serverEvents++;
					}
					beast.LastEventTime = now;
					if (IsDead(result.State))
					{
						MarkDead(beast, result.Source);
					}
					else if ((int)result.State != 0)
					{
						beast.Known = true;
						beast.Dead = false;
						beast.AliveSince = -1f;
					}
				}
			}
		}

		private static bool IsDead(ActorState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			return (state & 1) > 0;
		}

		private void MarkDead(Beast beast, string source)
		{
			if (beast.Dead)
			{
				return;
			}
			bool num = beast.Known || beast.HasPosition;
			beast.Known = true;
			beast.Dead = true;
			beast.AliveSince = -1f;
			if (num)
			{
				_pendingDeaths.Add(beast.Key);
				_detectedDeaths++;
				if (_diagnostics)
				{
					((MelonBase)this).LoggerInstance.Msg("DEATH: actor=" + beast.Key + " source=" + source + " AI=" + beast.IsAI + " positionKnown=" + beast.HasPosition);
				}
			}
		}

		private void Tick()
		{
			if (_insideTick)
			{
				return;
			}
			_insideTick = true;
			try
			{
				float unscaledTime = Time.unscaledTime;
				if (unscaledTime >= _nextSettings)
				{
					_nextSettings = unscaledTime + 0.5f;
					ReadPreferences();
				}
				if (unscaledTime >= _nextDiscovery)
				{
					_nextDiscovery = unscaledTime + 0.5f;
					DiscoverActorsAndReferences();
					SubscribeStateEvents();
				}
				if (unscaledTime >= _nextCameraScan)
				{
					_nextCameraScan = unscaledTime + 1f;
					DiscoverCameras();
					DiscoverComposers();
				}
				SampleBeasts(unscaledTime);
				ProcessStateEvents(unscaledTime);
				BuildCentroid();
				if (_pendingDeaths.Count > 0)
				{
					StartTransition();
					_pendingDeaths.Clear();
				}
				AdvanceTransition();
				ApplyDamping();
				if (unscaledTime >= _nextAI)
				{
					_nextAI = unscaledTime + 0.5f;
					ApplyAI();
				}
				if (_diagnostics && unscaledTime >= _nextStatus)
				{
					_nextStatus = unscaledTime + 10f;
					LogStatus(unscaledTime);
				}
			}
			catch (Exception exception)
			{
				Report("tick", exception);
			}
			finally
			{
				_insideTick = false;
			}
		}

		private void LogStatus(float now)
		{
			int num = 0;
			foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
			{
				RenderState value = renderer.Value;
				if (value.ReceivedBrainUpdate)
				{
					num++;
				}
				if (!value.ReceivedBrainUpdate && !value.Warned && (Object)(object)value.Camera != (Object)null && ((Behaviour)value.Camera).enabled && now - value.AttachedAt > 8f)
				{
					value.Warned = true;
					((MelonBase)this).LoggerInstance.Warning("No Cinemachine postfix update for camera: " + ((Object)value.Camera).name);
				}
			}
			((MelonBase)this).LoggerInstance.Msg("STATUS: actors=" + _beasts.Count + " living=" + _livingCount + " clientEvents=" + _clientEvents + " serverEvents=" + _serverEvents + " deaths=" + _detectedDeaths + " brainUpdates=" + num + "/" + _renderers.Count + " patchInstalled=" + _brainPatchInstalled + " strength=" + _strength + " subscribed=" + _clientSubscribed + "/" + _serverSubscribed);
		}

		private Beast Register(Actor actor)
		{
			if ((Object)(object)actor == (Object)null)
			{
				return null;
			}
			int instanceID = ((Object)actor).GetInstanceID();
			if (!_beasts.TryGetValue(instanceID, out var value))
			{
				value = new Beast
				{
					Key = instanceID,
					Actor = actor,
					IsAI = actor.IsAI
				};
				_beasts.Add(instanceID, value);
			}
			value.Actor = actor;
			return value;
		}

		private void DiscoverActorsAndReferences()
		{
			if ((Object)(object)_handler == (Object)null)
			{
				_handler = CMTargetGroupHandler.Instance;
				if ((Object)(object)_handler == (Object)null)
				{
					_handler = Object.FindObjectOfType<CMTargetGroupHandler>();
				}
			}
			if ((Object)(object)_pool == (Object)null)
			{
				_pool = CMTargetGroupPool.Instance;
				if ((Object)(object)_pool == (Object)null)
				{
					_pool = Object.FindObjectOfType<CMTargetGroupPool>();
				}
			}
			try
			{
				List<Actor> cachedActors = Actor.CachedActors;
				if (cachedActors != null)
				{
					for (int i = 0; i < cachedActors.Count; i++)
					{
						Register(cachedActors[i]);
					}
				}
			}
			catch (Exception exception)
			{
				Report("CachedActors", exception);
			}
			try
			{
				List<Actor> remoteActors = Actor.RemoteActors;
				if (remoteActors != null)
				{
					for (int j = 0; j < remoteActors.Count; j++)
					{
						Register(remoteActors[j]);
					}
				}
			}
			catch (Exception exception2)
			{
				Report("RemoteActors", exception2);
			}
			try
			{
				List<Actor> localPlayers = Actor.LocalPlayers;
				if (localPlayers != null)
				{
					for (int k = 0; k < localPlayers.Count; k++)
					{
						Register(localPlayers[k]);
					}
				}
			}
			catch (Exception exception3)
			{
				Report("LocalPlayers", exception3);
			}
			if ((Object)(object)_handler != (Object)null)
			{
				List<CMTrackedObject> trackedObjects = _handler.TrackedObjects;
				if (trackedObjects != null)
				{
					for (int l = 0; l < trackedObjects.Count; l++)
					{
						CMTrackedObject val = trackedObjects[l];
						if (val != null)
						{
							Register(val.beast);
						}
					}
				}
			}
			Il2CppArrayBase<Actor> val2 = Object.FindObjectsOfType<Actor>();
			if (val2 != null)
			{
				for (int m = 0; m < val2.Length; m++)
				{
					Register(val2[m]);
				}
			}
		}

		private void SampleBeasts(float now)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			_removeKeys.Clear();
			foreach (KeyValuePair<int, Beast> beast in _beasts)
			{
				Beast value = beast.Value;
				if ((Object)(object)value.Actor == (Object)null)
				{
					_removeKeys.Add(beast.Key);
					continue;
				}
				try
				{
					value.IsAI = value.Actor.IsAI;
					if ((Object)(object)value.Target == (Object)null || now >= value.NextTargetRefresh)
					{
						value.NextTargetRefresh = now + 0.5f;
						value.Root = ((Component)value.Actor).transform;
						value.Target = value.Actor.GetTrackingTransform();
						if ((Object)(object)value.Target == (Object)null)
						{
							value.Target = value.Root;
						}
					}
					ActorState actorState = value.Actor.actorState;
					ActorState network_actorState = value.Actor.Network_actorState;
					bool flag = IsDead(actorState) || IsDead(network_actorState);
					if (!value.Known)
					{
						value.Known = true;
						value.Dead = flag;
					}
					else if (flag)
					{
						MarkDead(value, IsDead(network_actorState) ? "Network_actorState" : "actorState");
					}
					else if (value.Dead && now - value.LastEventTime > 1f)
					{
						if (value.AliveSince < 0f)
						{
							value.AliveSince = now;
						}
						if (now - value.AliveSince >= 1f)
						{
							value.Dead = false;
							value.AliveSince = -1f;
						}
					}
					if ((!value.Dead || !value.HasPosition) && TryPosition(value.Target, out var position))
					{
						value.Position = position;
						value.HasPosition = true;
					}
				}
				catch (Exception exception)
				{
					Report("sample beast", exception);
				}
			}
			for (int i = 0; i < _removeKeys.Count; i++)
			{
				_beasts.Remove(_removeKeys[i]);
			}
		}

		private void BuildCentroid()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			int num = 0;
			foreach (KeyValuePair<int, Beast> beast in _beasts)
			{
				Beast value = beast.Value;
				if ((Object)(object)value.Actor == (Object)null || value.Dead || !value.HasPosition)
				{
					continue;
				}
				try
				{
					if (!((Component)value.Actor).gameObject.activeInHierarchy)
					{
						continue;
					}
				}
				catch
				{
					continue;
				}
				val += value.Position;
				num++;
			}
			_livingCount = num;
			_centroid = ((num > 0) ? (val / (float)num) : Vector3.zero);
		}

		private void StartTransition()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			Beast beast = null;
			for (int i = 0; i < _pendingDeaths.Count; i++)
			{
				if (_beasts.TryGetValue(_pendingDeaths[i], out var value))
				{
					beast = value;
					if (value.HasPosition)
					{
						break;
					}
				}
			}
			if (beast != null && !(_strength <= 0f))
			{
				Vector3 val = Vector3.zero;
				if (beast.HasPosition && _livingCount > 0)
				{
					val = beast.Position - _centroid;
					val.y = 0f;
					val = Vector3.ClampMagnitude(val, _sideReach);
				}
				_startOffset = DisplayOffset();
				_peakOffset = Vector3.ClampMagnitude((val + Vector3.up * _depth) * _strength, _maxOffset);
				_offset = _startOffset;
				_dipProgress = 0f;
				_returnProgress = 0f;
				_seed = beast.Key;
				_startFrame = Time.frameCount;
				_transitionId++;
				_moving = true;
				if (_diagnostics)
				{
					((MelonBase)this).LoggerInstance.Msg("TRANSITION START: #" + _transitionId + " actor=" + beast.Key + " cameras=" + _renderers.Count + " strength=" + _strength);
				}
			}
		}

		private void AdvanceTransition()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			int frameCount = Time.frameCount;
			if (_advancedFrame == frameCount)
			{
				return;
			}
			_advancedFrame = frameCount;
			if (_moving && frameCount != _startFrame)
			{
				float num = Mathf.Max(0f, Time.deltaTime);
				if (_dipProgress < 1f)
				{
					float num2 = Mathf.Min((1f - _dipProgress) * _dipTime, num);
					_dipProgress = Mathf.Clamp01(_dipProgress + num2 / _dipTime);
					num -= num2;
					_offset = Vector3.Lerp(_startOffset, _peakOffset, Curve(_dipProgress));
				}
				if (_dipProgress >= 1f)
				{
					_returnProgress = Mathf.Clamp01(_returnProgress + num / _returnTime);
					_offset = Vector3.Lerp(_peakOffset, Vector3.zero, Curve(_returnProgress));
				}
				if (_returnProgress >= 1f)
				{
					_moving = false;
					_offset = Vector3.zero;
					_startOffset = Vector3.zero;
				}
			}
		}

		private Vector3 DisplayOffset()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!_moving)
			{
				return Vector3.zero;
			}
			float num = _dipProgress + _returnProgress;
			float num2 = Mathf.Sin((float)Math.PI * Mathf.Clamp01(num * 0.5f));
			num2 *= num2;
			float num3 = (float)(_seed & 0x3FF) * 0.071f;
			Vector3 val = new Vector3(Mathf.Sin(num * 10f + num3), Mathf.Sin(num * 8f + num3) * 0.35f, Mathf.Sin(num * 9f + num3) * 0.25f) * (_roughness * num2);
			return Vector3.ClampMagnitude(_offset + val, _maxOffset);
		}

		private RenderState FindRenderState(Camera camera)
		{
			if ((Object)(object)camera == (Object)null)
			{
				return null;
			}
			foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
			{
				RenderState value = renderer.Value;
				if ((Object)(object)value.Camera != (Object)null && (Object)(object)value.Driver != (Object)null && ((Il2CppObjectBase)value.Camera).Pointer == ((Il2CppObjectBase)camera).Pointer)
				{
					return value;
				}
			}
			return null;
		}

		private void DiscoverCameras()
		{
			_knownCameras.Clear();
			_removeRenderers.Clear();
			foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
			{
				RenderState value = renderer.Value;
				if ((Object)(object)value.Camera == (Object)null || (Object)(object)value.Driver == (Object)null)
				{
					_removeRenderers.Add(renderer.Key);
				}
				else
				{
					_knownCameras.Add(((Il2CppObjectBase)value.Camera).Pointer);
				}
			}
			for (int i = 0; i < _removeRenderers.Count; i++)
			{
				IntPtr key = _removeRenderers[i];
				if (_renderers.TryGetValue(key, out var value2))
				{
					Detach(value2);
				}
				_renderers.Remove(key);
			}
			Il2CppArrayBase<Camera> val = Object.FindObjectsOfType<Camera>();
			bool flag = false;
			if (val != null)
			{
				for (int j = 0; j < val.Length; j++)
				{
					Camera val2 = val[j];
					if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).GetComponent<CinemachineBrain>() == (Object)null))
					{
						flag = true;
						Attach(val2);
					}
				}
			}
			if (!flag && (Object)(object)Camera.main != (Object)null)
			{
				Attach(Camera.main);
			}
		}

		private void Attach(Camera camera)
		{
			if (!((Object)(object)camera == (Object)null) && !_knownCameras.Contains(((Il2CppObjectBase)camera).Pointer))
			{
				OldCameraRenderDriver oldCameraRenderDriver = ((Component)camera).GetComponent<OldCameraRenderDriver>();
				if ((Object)(object)oldCameraRenderDriver == (Object)null)
				{
					oldCameraRenderDriver = ((Component)camera).gameObject.AddComponent<OldCameraRenderDriver>();
				}
				((Behaviour)oldCameraRenderDriver).enabled = true;
				_renderers[((Il2CppObjectBase)oldCameraRenderDriver).Pointer] = new RenderState
				{
					Camera = camera,
					Transform = ((Component)camera).transform,
					Driver = oldCameraRenderDriver,
					AttachedAt = Time.unscaledTime
				};
				_knownCameras.Add(((Il2CppObjectBase)camera).Pointer);
				((MelonBase)this).LoggerInstance.Msg("CAMERA REGISTERED: " + ((Object)camera).name + " enabled=" + ((Behaviour)camera).enabled);
			}
		}

		internal void AfterRender(OldCameraRenderDriver driver)
		{
			if ((Object)(object)driver != (Object)null && _renderers.TryGetValue(((Il2CppObjectBase)driver).Pointer, out var value))
			{
				RestorePosition(value);
				value.HasDisplayedPosition = false;
				value.SmoothingMovement = false;
				value.LastDisplayedFrame = -1;
				value.LastSmoothingFrame = -1;
			}
		}

		private static void RestorePosition(RenderState state)
		{
			//IL_001e: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!state.Applied)
			{
				return;
			}
			try
			{
				if ((Object)(object)state.Transform != (Object)null)
				{
					Vector3 val = state.Transform.position - state.WrittenPosition;
					if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
					{
						state.Transform.position = state.BasePosition;
					}
				}
			}
			catch
			{
			}
			state.Applied = false;
		}

		private static void Detach(RenderState state)
		{
			RestorePosition(state);
			if ((Object)(object)state.Driver != (Object)null)
			{
				try
				{
					((Behaviour)state.Driver).enabled = false;
					Object.Destroy((Object)(object)state.Driver);
				}
				catch
				{
				}
			}
			state.HasDisplayedPosition = false;
			state.SmoothingMovement = false;
			state.Driver = null;
			state.Camera = null;
			state.Transform = null;
		}

		private void ApplyAI()
		{
			if ((Object)(object)_handler != (Object)null && !_aiCached)
			{
				_originalTrackAI = _handler.TrackAI;
				_originalAIWeight = CMTargetGroupHandler._AITrackingWeight;
				_originalAIRadius = CMTargetGroupHandler._AITrackingRadius;
				_aiCached = true;
			}
			if ((Object)(object)_handler != (Object)null && _aiCached)
			{
				_handler.TrackAI = _trackAI || _originalTrackAI;
				CMTargetGroupHandler._AITrackingWeight = (_trackAI ? 1f : _originalAIWeight);
				CMTargetGroupHandler._AITrackingRadius = (_trackAI ? 2f : _originalAIRadius);
			}
			if ((Object)(object)_pool == (Object)null)
			{
				return;
			}
			TargetGroupAndTrackingInfo allLiving = _pool.AllLiving;
			CinemachineTargetGroup val = ((allLiving != null) ? allLiving.group : null);
			if (!((Object)(object)val != (Object)null) || !((Object)(object)_aiGroup != (Object)null) || !(((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)_aiGroup).Pointer))
			{
				RemoveAddedAI();
				_aiGroup = val;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			_removeKeys.Clear();
			foreach (KeyValuePair<int, Transform> item in _addedAI)
			{
				if (_trackAI && _beasts.TryGetValue(item.Key, out var value) && (Object)(object)value.Actor != (Object)null && !value.Dead && (Object)(object)value.Target != (Object)null && (Object)(object)item.Value != (Object)null && ((Il2CppObjectBase)value.Target).Pointer == ((Il2CppObjectBase)item.Value).Pointer)
				{
					continue;
				}
				if ((Object)(object)item.Value != (Object)null)
				{
					try
					{
						val.RemoveMember(item.Value);
					}
					catch
					{
					}
				}
				_removeKeys.Add(item.Key);
			}
			for (int i = 0; i < _removeKeys.Count; i++)
			{
				_addedAI.Remove(_removeKeys[i]);
			}
			if (!_trackAI)
			{
				return;
			}
			foreach (KeyValuePair<int, Beast> beast in _beasts)
			{
				Beast value2 = beast.Value;
				if (value2.IsAI && !((Object)(object)value2.Actor == (Object)null) && !value2.Dead && value2.HasPosition && !((Object)(object)value2.Target == (Object)null) && ((Component)value2.Actor).gameObject.activeInHierarchy && !ContainsBeast(val, value2))
				{
					val.AddMember(value2.Target, 1f, 2f);
					_addedAI[value2.Key] = value2.Target;
				}
			}
		}

		private static bool ContainsBeast(CinemachineTargetGroup group, Beast beast)
		{
			Il2CppReferenceArray<Target> targets = group.m_Targets;
			if (targets == null)
			{
				return false;
			}
			for (int i = 0; i < ((Il2CppArrayBase<Target>)(object)targets).Length; i++)
			{
				Transform target = ((Il2CppArrayBase<Target>)(object)targets)[i].target;
				if ((Object)(object)target == (Object)null)
				{
					continue;
				}
				if ((Object)(object)beast.Target != (Object)null && ((Il2CppObjectBase)target).Pointer == ((Il2CppObjectBase)beast.Target).Pointer)
				{
					return true;
				}
				Transform val = target;
				int num = 0;
				while ((Object)(object)val != (Object)null && num < 32)
				{
					if ((Object)(object)beast.Root != (Object)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)beast.Root).Pointer)
					{
						return true;
					}
					val = val.parent;
					num++;
				}
			}
			return false;
		}

		private void RemoveAddedAI()
		{
			if ((Object)(object)_aiGroup != (Object)null)
			{
				foreach (KeyValuePair<int, Transform> item in _addedAI)
				{
					if (!((Object)(object)item.Value == (Object)null))
					{
						try
						{
							_aiGroup.RemoveMember(item.Value);
						}
						catch
						{
						}
					}
				}
			}
			_addedAI.Clear();
			_aiGroup = null;
		}

		private void DiscoverComposers()
		{
			for (int num = _composers.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)_composers[num].Composer == (Object)null)
				{
					_composers.RemoveAt(num);
				}
			}
			_knownComposers.Clear();
			for (int i = 0; i < _composers.Count; i++)
			{
				_knownComposers.Add(((Il2CppObjectBase)_composers[i].Composer).Pointer);
			}
			Il2CppArrayBase<GangBeastsGroupComposer> val = Object.FindObjectsOfType<GangBeastsGroupComposer>();
			if (val == null)
			{
				return;
			}
			for (int j = 0; j < val.Length; j++)
			{
				GangBeastsGroupComposer val2 = val[j];
				if (!((Object)(object)val2 == (Object)null) && _knownComposers.Add(((Il2CppObjectBase)val2).Pointer))
				{
					_composers.Add(new ComposerState
					{
						Composer = val2,
						Original = val2.m_FrameDamping,
						Applied = val2.m_FrameDamping
					});
				}
			}
		}

		private void ApplyDamping()
		{
			for (int i = 0; i < _composers.Count; i++)
			{
				ComposerState composerState = _composers[i];
				if ((Object)(object)composerState.Composer != (Object)null)
				{
					composerState.Composer.m_FrameDamping = _damping;
					composerState.Applied = _damping;
				}
			}
		}

		private void InitializePreferences()
		{
			_category = MelonPreferences.CreateCategory("OldCameraNetwork", "OldCamera Network");
			_pTrackAI = _category.CreateEntry<bool>("TrackAI", true, "Track AI", (string)null, false, false, (ValueValidator)null, (string)null);
			_pDiagnostics = _category.CreateEntry<bool>("Diagnostics", true, "Log network and camera stages", (string)null, false, false, (ValueValidator)null, (string)null);
			_pDipTime = _category.CreateEntry<float>("DipDuration", 0.85f, "Dip duration in seconds", (string)null, false, false, (ValueValidator)null, (string)null);
			_pReturnTime = _category.CreateEntry<float>("ReturnDuration", 2.4f, "Return duration in seconds", (string)null, false, false, (ValueValidator)null, (string)null);
			_pDepth = _category.CreateEntry<float>("DipDepth", -1.25f, "Negative moves down", (string)null, false, false, (ValueValidator)null, (string)null);
			_pSideReach = _category.CreateEntry<float>("SidewaysReach", 0.65f, "Horizontal movement limit", (string)null, false, false, (ValueValidator)null, (string)null);
			_pStrength = _category.CreateEntry<float>("Strength", 1.5f, "Death movement strength", (string)null, false, false, (ValueValidator)null, (string)null);
			_pRoughness = _category.CreateEntry<float>("Roughness", 0.022f, "Small motion unevenness", (string)null, false, false, (ValueValidator)null, (string)null);
			_pMaxOffset = _category.CreateEntry<float>("MaximumOffset", 3f, "Death offset limit", (string)null, false, false, (ValueValidator)null, (string)null);
			_pDamping = _category.CreateEntry<float>("CameraDamping", 4.5f, "Composer damping", (string)null, false, false, (ValueValidator)null, (string)null);
			ReadPreferences();
		}

		private void ReadPreferences()
		{
			_trackAI = _pTrackAI.Value;
			_diagnostics = _pDiagnostics.Value;
			_dipTime = Safe(_pDipTime.Value, 0.85f, 0.1f, 8f);
			_returnTime = Safe(_pReturnTime.Value, 2.4f, 0.2f, 12f);
			_depth = Safe(_pDepth.Value, -1.25f, -5f, 0f);
			_sideReach = Safe(_pSideReach.Value, 0.65f, 0f, 2f);
			_strength = Safe(_pStrength.Value, 1.5f, 0f, 2f);
			_roughness = Safe(_pRoughness.Value, 0.022f, 0f, 0.2f);
			_maxOffset = Safe(_pMaxOffset.Value, 3f, 0.1f, 5f);
			_damping = Safe(_pDamping.Value, 4.5f, 0.1f, 20f);
		}

		private void Cleanup()
		{
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			_acceptEvents = false;
			UnsubscribeStateEvents();
			StateMessage result;
			while (_stateQueue.TryDequeue(out result))
			{
			}
			foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
			{
				Detach(renderer.Value);
			}
			_renderers.Clear();
			_knownCameras.Clear();
			_removeRenderers.Clear();
			RemoveAddedAI();
			if (_aiCached)
			{
				CMTargetGroupHandler._AITrackingWeight = _originalAIWeight;
				CMTargetGroupHandler._AITrackingRadius = _originalAIRadius;
				if ((Object)(object)_handler != (Object)null)
				{
					try
					{
						_handler.TrackAI = _originalTrackAI;
					}
					catch
					{
					}
				}
			}
			_aiCached = false;
			foreach (ComposerState composer in _composers)
			{
				if ((Object)(object)composer.Composer == (Object)null)
				{
					continue;
				}
				try
				{
					if (Mathf.Abs(composer.Composer.m_FrameDamping - composer.Applied) < 0.0001f)
					{
						composer.Composer.m_FrameDamping = composer.Original;
					}
				}
				catch
				{
				}
			}
			_composers.Clear();
			_knownComposers.Clear();
			_beasts.Clear();
			_removeKeys.Clear();
			_pendingDeaths.Clear();
			_handler = null;
			_pool = null;
			_moving = false;
			_offset = Vector3.zero;
			_startOffset = Vector3.zero;
			_peakOffset = Vector3.zero;
			_dipProgress = 0f;
			_returnProgress = 0f;
			_startFrame = -1;
			_advancedFrame = -1;
			_livingCount = 0;
			_centroid = Vector3.zero;
			_insideTick = false;
			_insideRender = false;
			_nextDiscovery = 0f;
			_nextCameraScan = 0f;
			_nextSettings = 0f;
			_nextAI = 0f;
			_nextStatus = 0f;
			_clientEvents = 0;
			_serverEvents = 0;
			_detectedDeaths = 0;
		}

		private static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		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_0039: 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)
			if (Finite(value.x) && Finite(value.y) && Finite(value.z) && Mathf.Abs(value.x) < 100000f && Mathf.Abs(value.y) < 100000f)
			{
				return Mathf.Abs(value.z) < 100000f;
			}
			return false;
		}

		private static bool TryPosition(Transform target, out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0024: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			try
			{
				position = target.position;
				return Finite(position);
			}
			catch
			{
				return false;
			}
		}

		private static float Curve(float value)
		{
			float num = Mathf.Clamp01(value);
			return num * num * num * (num * (num * 6f - 15f) + 10f);
		}

		private static float Safe(float value, float fallback, float min, float max)
		{
			return Mathf.Clamp(Finite(value) ? value : fallback, min, max);
		}

		private void Report(string operation, Exception exception)
		{
			float unscaledTime = Time.unscaledTime;
			if (!(unscaledTime - _lastError < 5f))
			{
				_lastError = unscaledTime;
				((MelonBase)this).LoggerInstance.Error(operation + " failed: " + exception);
			}
		}
	}
}