Decompiled source of WigglesBW Timeline Add On v2.9.4

Mods/WigglesBW.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using AC130;
using AirRack;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using Cram;
using Flyby;
using FpvDrone;
using Grapple;
using GunJam;
using HarmonyLib;
using Heli;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Data;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.VRMK;
using MagPalm;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using MenuManager;
using NightVision;
using NoNpcs;
using Nuke;
using RagdollReload;
using Sling;
using TimelineClones;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.XR;
using Wiggles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: MelonInfo(typeof(WigglesBW), "Wiggles BW", "2.9.4", "adama", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion", "Timeline" })]
[assembly: HarmonyDontPatchAll]
[assembly: MelonPriority(-10000)]
[assembly: InternalsVisibleTo("WigglesBW.Fusion")]
[assembly: InternalsVisibleTo("WigglesBW.Timeline")]
[assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)]
[assembly: AssemblyVersion("2.9.4.0")]
[module: UnverifiableCode]
namespace TimelineClones
{
	internal static class BloodFx
	{
		private const int PoolSize = 64;

		private static Transform _root;

		private static ParticleSystem _drops;

		private static ParticleSystem _mist;

		private static Transform[] _pool;

		private static MeshRenderer[] _poolRenderers;

		private static int _next;

		private static Material[] _splatMats;

		private static Il2CppStructArray<RaycastHit> _hits;

		private static readonly Color Arterial = new Color(0.3f, 0.012f, 0.012f, 1f);

		private static readonly Color Venous = new Color(0.12f, 0.004f, 0.006f, 1f);

		internal static bool Replaying;

		internal static void EnsureBuilt()
		{
			//IL_0013: 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: Expected O, but got Unknown
			//IL_003c: 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_0055: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0076: Expected O, but got Unknown
			//IL_0076: Expected O, but got Unknown
			//IL_008c: 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_00b9: 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_00ee: Expected O, but got Unknown
			//IL_00ee: Expected O, but got Unknown
			//IL_00ee: Expected O, but got Unknown
			if (!((Object)(object)_drops != (Object)null))
			{
				GameObject val = new GameObject("TimelineClones_Blood");
				Object.DontDestroyOnLoad((Object)val);
				_root = val.transform;
				_drops = MakeParticles("Droplets", 500, new MinMaxCurve(0.6f, 1.3f), new MinMaxCurve(0.006f, 0.022f), 1.6f, new MinMaxGradient(Venous, Arterial), Dot(16, 0.9f), stretch: true);
				_mist = MakeParticles("Mist", 120, new MinMaxCurve(0.12f, 0.3f), new MinMaxCurve(0.05f, 0.14f), 0.05f, new MinMaxGradient(new Color(0.28f, 0.02f, 0.02f, 0.35f), new Color(0.16f, 0.01f, 0.01f, 0.2f)), Dot(32, 0.5f), stretch: false);
				_splatMats = (Material[])(object)new Material[4];
				for (int i = 0; i < _splatMats.Length; i++)
				{
					_splatMats[i] = Unlit(SplatTexture(128, i), 3040);
				}
				_pool = (Transform[])(object)new Transform[64];
				_poolRenderers = (MeshRenderer[])(object)new MeshRenderer[64];
				for (int j = 0; j < 64; j++)
				{
					GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)5);
					((Object)val2).name = "BloodSplat";
					Object.Destroy((Object)(object)val2.GetComponent<Collider>());
					MeshRenderer component = val2.GetComponent<MeshRenderer>();
					((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)component).receiveShadows = false;
					val2.transform.SetParent(_root, false);
					val2.SetActive(false);
					_pool[j] = val2.transform;
					_poolRenderers[j] = component;
				}
			}
		}

		internal static void Hit(Vector3 point, Vector3 dir, Vector3 surfaceNormal, float amount)
		{
			//IL_0014: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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_01ae: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: 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_00d3: 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_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: 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_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			if (!ClonesMod.Blood.Value)
			{
				return;
			}
			if (!Replaying)
			{
				ClonesMod.OnBlood(point, dir, surfaceNormal, amount);
			}
			EnsureBuilt();
			amount = Mathf.Clamp(amount * ClonesMod.BloodAmount.Value, 0.2f, 3f);
			dir = ((((Vector3)(ref dir)).sqrMagnitude > 1E-06f) ? ((Vector3)(ref dir)).normalized : Vector3.down);
			Vector3 val = ((((Vector3)(ref surfaceNormal)).sqrMagnitude > 0.01f) ? ((Vector3)(ref surfaceNormal)).normalized : (-dir));
			EmitParams val2 = default(EmitParams);
			((EmitParams)(ref val2)).applyShapeToPosition = false;
			EmitParams val3 = val2;
			int num = Mathf.RoundToInt(22f * amount);
			Vector3 val4;
			for (int i = 0; i < num; i++)
			{
				bool flag = i % 4 == 0;
				val4 = (flag ? val : dir) + Random.insideUnitSphere * (flag ? 0.5f : 0.35f);
				Vector3 velocity = ((Vector3)(ref val4)).normalized * Random.Range(1.5f, flag ? 3f : 6f);
				((EmitParams)(ref val3)).position = point + Random.insideUnitSphere * 0.015f;
				((EmitParams)(ref val3)).velocity = velocity;
				((EmitParams)(ref val3)).startSize = Random.Range(0.006f, 0.022f) * (flag ? 0.8f : 1f);
				_drops.Emit(val3, 1);
			}
			val2 = default(EmitParams);
			((EmitParams)(ref val2)).applyShapeToPosition = false;
			EmitParams val5 = val2;
			int num2 = Mathf.RoundToInt(5f * amount);
			for (int j = 0; j < num2; j++)
			{
				((EmitParams)(ref val5)).position = point;
				((EmitParams)(ref val5)).velocity = (val * 0.6f + dir * 0.4f + Random.insideUnitSphere * 0.5f) * Random.Range(0.3f, 1.2f);
				_mist.Emit(val5, 1);
			}
			int num3 = Mathf.Clamp(Mathf.RoundToInt(3f * amount), 1, 6);
			for (int k = 0; k < num3; k++)
			{
				val4 = dir + Random.insideUnitSphere * ((k == 0) ? 0.05f : 0.3f);
				Vector3 normalized = ((Vector3)(ref val4)).normalized;
				if (CastSurface(point + normalized * 0.1f, normalized, 3f, out var best))
				{
					float size = ((k == 0) ? Random.Range(0.18f, 0.32f) : Random.Range(0.06f, 0.16f)) * Mathf.Sqrt(amount);
					PlaceSplat(best, normalized, size, (k != 0) ? 1 : Random.Range(0, 2));
				}
			}
			int num4 = Mathf.Clamp(Mathf.RoundToInt(2f * amount), 1, 4);
			for (int l = 0; l < num4; l++)
			{
				if (CastSurface(point + new Vector3(Random.Range(-0.25f, 0.25f), 0f, Random.Range(-0.25f, 0.25f)), Vector3.down, 3f, out var best2))
				{
					PlaceSplat(best2, Vector3.down, Random.Range(0.04f, 0.1f), 3);
				}
			}
		}

		internal static void Clear()
		{
			if (_pool == null)
			{
				return;
			}
			Transform[] pool = _pool;
			foreach (Transform val in pool)
			{
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			if ((Object)(object)_drops != (Object)null)
			{
				_drops.Clear();
			}
			if ((Object)(object)_mist != (Object)null)
			{
				_mist.Clear();
			}
		}

		private static void PlaceSplat(RaycastHit hit, Vector3 travel, float size, int variant)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0157: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: 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_0210: Unknown result type (might be due to invalid IL or missing references)
			int next = _next;
			_next = (_next + 1) % 64;
			Transform val = _pool[next];
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)val2).name = "BloodSplat";
				Object.Destroy((Object)(object)val2.GetComponent<Collider>());
				_poolRenderers[next] = val2.GetComponent<MeshRenderer>();
				((Renderer)_poolRenderers[next]).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)_poolRenderers[next]).receiveShadows = false;
				val = (_pool[next] = val2.transform);
			}
			Vector3 normal = ((RaycastHit)(ref hit)).normal;
			Vector3 val3 = Vector3.ProjectOnPlane(travel, normal);
			float magnitude = ((Vector3)(ref val3)).magnitude;
			bool flag = magnitude > 0.55f;
			if (flag)
			{
				variant = 2;
			}
			Rigidbody attachedRigidbody = ((RaycastHit)(ref hit)).collider.attachedRigidbody;
			val.SetParent(((Object)(object)attachedRigidbody != (Object)null) ? ((Component)((RaycastHit)(ref hit)).collider).transform : _root, true);
			((Component)val).gameObject.SetActive(true);
			((Renderer)_poolRenderers[next]).sharedMaterial = _splatMats[variant];
			val.position = ((RaycastHit)(ref hit)).point + normal * 0.004f;
			Vector3 val4;
			Vector3 normalized;
			if (!(magnitude > 0.05f))
			{
				val4 = Vector3.ProjectOnPlane(Random.onUnitSphere, normal);
				normalized = ((Vector3)(ref val4)).normalized;
			}
			else
			{
				normalized = ((Vector3)(ref val3)).normalized;
			}
			Vector3 val5 = normalized;
			if (((Vector3)(ref val5)).sqrMagnitude < 0.01f)
			{
				val4 = Vector3.ProjectOnPlane(Vector3.up, normal);
				val5 = ((Vector3)(ref val4)).normalized;
			}
			if (((Vector3)(ref val5)).sqrMagnitude < 0.01f)
			{
				val5 = Vector3.forward;
			}
			val.rotation = Quaternion.LookRotation(-normal, val5);
			float num = (flag ? Mathf.Lerp(1.6f, 3f, magnitude) : 1f);
			Vector3 val6 = (((Object)(object)val.parent != (Object)null) ? val.parent.lossyScale : Vector3.one);
			float num2 = 1f / Mathf.Max(Mathf.Abs(val6.x), 0.0001f);
			val.localScale = new Vector3(size * (flag ? 0.6f : 1f), size * num, 1f) * num2;
		}

		private static bool CastSurface(Vector3 origin, Vector3 dir, float dist, out RaycastHit best)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_004b: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			best = default(RaycastHit);
			if (_hits == null)
			{
				_hits = new Il2CppStructArray<RaycastHit>(12L);
			}
			int num = Physics.RaycastNonAlloc(origin, dir, _hits, dist, -5, (QueryTriggerInteraction)1);
			float num2 = 3.4028235E+38f;
			bool result = false;
			RigManager rigManager = Player.RigManager;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i];
				Collider collider = ((RaycastHit)(ref val)).collider;
				if (!((Object)(object)collider == (Object)null) && !(((RaycastHit)(ref val)).distance >= num2) && ((Component)collider).gameObject.layer != 12 && (!((Object)(object)rigManager != (Object)null) || !((Object)(object)((Component)collider).GetComponentInParent<RigManager>() == (Object)(object)rigManager)))
				{
					num2 = ((RaycastHit)(ref val)).distance;
					best = val;
					result = true;
				}
			}
			return result;
		}

		private static ParticleSystem MakeParticles(string name, int max, MinMaxCurve life, MinMaxCurve size, float gravity, MinMaxGradient color, Texture2D tex, bool stretch)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(_root, false);
			ParticleSystem obj = val.AddComponent<ParticleSystem>();
			obj.Stop(true, (ParticleSystemStopBehavior)0);
			MainModule main = obj.main;
			main.loop = false;
			main.playOnAwake = false;
			main.maxParticles = max;
			main.simulationSpace = (ParticleSystemSimulationSpace)1;
			main.startLifetime = life;
			main.startSize = size;
			main.startSpeed = new MinMaxCurve(0f);
			main.gravityModifier = new MinMaxCurve(gravity);
			main.startColor = color;
			obj.emission.enabled = false;
			ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
			((Renderer)component).sharedMaterial = Unlit(tex, 3050);
			((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component).receiveShadows = false;
			if (stretch)
			{
				component.renderMode = (ParticleSystemRenderMode)1;
				component.velocityScale = 0.035f;
				component.lengthScale = 1.2f;
			}
			return obj;
		}

		private static Material Unlit(Texture2D tex, int queue)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(Shader.Find("UI/Default") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Universal Render Pipeline/Unlit"))
			{
				hideFlags = (HideFlags)32,
				renderQueue = queue
			};
			if (val.HasProperty("_MainTex"))
			{
				val.SetTexture("_MainTex", (Texture)(object)tex);
			}
			if (val.HasProperty("_BaseMap"))
			{
				val.SetTexture("_BaseMap", (Texture)(object)tex);
			}
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", Color.white);
			}
			return val;
		}

		private static Texture2D Dot(int size, float hardness)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[size * size];
			float num = (float)(size - 1) * 0.5f;
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num2 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)) / num;
					float num3 = Mathf.Clamp01((1f - num2) / Mathf.Max(1f - hardness, 0.05f));
					array[i * size + j] = new Color32((byte)255, (byte)255, (byte)255, (byte)(num3 * 255f));
				}
			}
			return Upload(array, size);
		}

		private static Texture2D SplatTexture(int size, int variant)
		{
			//IL_0115: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[size * size];
			float num = (float)(size - 1) * 0.5f;
			uint seed = (uint)(9000 + variant * 7919);
			float[] array2 = new float[8];
			float[] array3 = new float[8];
			for (int i = 0; i < 8; i++)
			{
				array2[i] = (0.05f + Rand() * 0.07f) / (1f + (float)i * 0.6f);
				array3[i] = Rand() * (float)Math.PI * 2f;
			}
			Vector3[] array4 = (Vector3[])(object)new Vector3[variant switch
			{
				2 => 10, 
				1 => 18, 
				_ => 0, 
			}];
			for (int j = 0; j < array4.Length; j++)
			{
				float num2 = Rand() * (float)Math.PI * 2f;
				float num3 = 0.55f + Rand() * 0.4f;
				Vector2 val = ((variant == 2) ? new Vector2((Rand() - 0.5f) * 0.2f, 0.62f + Rand() * 0.33f) : new Vector2(Mathf.Cos(num2) * num3, Mathf.Sin(num2) * num3));
				array4[j] = new Vector3(val.x, val.y, 0.025f + Rand() * ((variant == 2) ? 0.05f : 0.06f));
			}
			for (int k = 0; k < size; k++)
			{
				for (int l = 0; l < size; l++)
				{
					float num4 = ((float)l - num) / num;
					float num5 = ((float)k - num) / num;
					float num13;
					if (variant == 2)
					{
						float num6 = Mathf.Atan2(num5 + 0.35f, num4);
						float num7 = 0.38f + 0.04f * Mathf.Sin(num6 * 3f + array3[0]) + 0.025f * Mathf.Sin(num6 * 7f + array3[1]);
						float num8 = Mathf.Sqrt(num4 * num4 + (num5 + 0.35f) * (num5 + 0.35f)) / num7;
						float num9 = Mathf.InverseLerp(-0.35f, 0.6f, num5);
						float num10 = Mathf.Lerp(0.3f, 0.015f, Mathf.Sqrt(num9));
						float num11 = 0.02f * Mathf.Sin(num5 * 9f + array3[2]);
						float num12 = ((num5 > -0.35f && num5 < 0.6f) ? (Mathf.Abs(num4 - num11) / num10) : 9f);
						num13 = Mathf.Clamp01((1f - Mathf.Min(num8, num12)) * 5f);
					}
					else
					{
						float num14 = Mathf.Sqrt(num4 * num4 + num5 * num5);
						float num15 = Mathf.Atan2(num5, num4);
						float num16 = variant switch
						{
							1 => 0.36f, 
							3 => 0.42f, 
							_ => 0.6f, 
						};
						for (int m = 0; m < 8; m++)
						{
							num16 += array2[m] * Mathf.Sin(num15 * (float)(m + 2) + array3[m]);
						}
						if (variant == 1)
						{
							num16 += 0.18f * Mathf.Pow(Mathf.Max(0f, Mathf.Sin(num15 * 3f + array3[3]) * Mathf.Sin(num15 * 5f + array3[4])), 6f);
						}
						num13 = Mathf.Clamp01((num16 - num14) * 12f);
					}
					Vector3[] array5 = array4;
					foreach (Vector3 val2 in array5)
					{
						float num17 = Mathf.Sqrt((num4 - val2.x) * (num4 - val2.x) + (num5 - val2.y) * (num5 - val2.y));
						num13 = Mathf.Max(num13, Mathf.Clamp01((val2.z - num17) * 60f));
					}
					float num18 = Mathf.Sqrt(num4 * num4 + num5 * num5);
					float num19 = Mathf.Clamp01(1f - num18 * 1.3f);
					float num20 = Mathf.PerlinNoise((float)l * 0.09f + (float)variant * 3f, (float)k * 0.09f);
					float num21 = Mathf.Lerp(34f, 80f, num19 * 0.7f + num20 * 0.3f);
					array[k * size + l] = new Color32((byte)num21, (byte)(num21 * 0.04f), (byte)(num21 * 0.04f), (byte)(num13 * 240f));
				}
			}
			return Upload(array, size);
			[CompilerGenerated]
			float Rand()
			{
				seed = seed * 1664525 + 1013904223;
				return (float)(seed >> 8) / 16777216f;
			}
		}

		private static Texture2D Upload(Color32[] px, int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0035: Expected O, but got Unknown
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, true)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)32
			};
			val.SetPixels32(Il2CppStructArray<Color32>.op_Implicit(px), 0);
			val.Apply(true, true);
			return val;
		}
	}
	public class CloneHitbox : MonoBehaviour
	{
		private static bool _tried;

		internal CloneBody Body;

		internal Transform Bone;

		internal Rigidbody Rb;

		internal Collider Col;

		[field: CompilerGenerated]
		internal static bool Injected
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public CloneHitbox(global::System.IntPtr ptr)
			: base(ptr)
		{
		}

		internal static bool EnsureInjected()
		{
			if (Injected || _tried)
			{
				return Injected;
			}
			_tried = true;
			if (CrashGuard.IsOff("hook:clone-hitbox"))
			{
				return false;
			}
			CrashGuard.Stage("hook:clone-hitbox");
			try
			{
				ClassInjector.RegisterTypeInIl2Cpp<CloneHitbox>();
				Injected = true;
				ClonesMod.Log.Msg("Clone hitboxes ready");
			}
			catch (global::System.Exception ex)
			{
				ClonesMod.Log.Warning("Clone hitboxes unavailable: " + ex.Message);
			}
			CrashGuard.Stage("playing");
			return Injected;
		}

		public void OnCollisionEnter(Collision collision)
		{
			try
			{
				Body?.OnCollision(this, collision);
			}
			catch (global::System.Exception ex)
			{
				ClonesMod.Log.Warning("Clone hit failed: " + ex.Message);
			}
		}
	}
	internal class CloneBody
	{
		private class Piercing
		{
			public Rigidbody Blade;

			public CloneBody Body;

			public Collider[] BladeCols;

			public HashSet<global::System.IntPtr> OwnJoints;

			public InteractableHost Host;

			public StabSlash Slash;

			public float Since;

			public bool Hit;
		}

		private const int EnemyLayer = 12;

		private const string FleshBarcode = "SLZ.Backlot.SurfaceDataCard.Blood";

		internal Avatar Avatar;

		internal Animator Anim;

		internal float Height = 1.76f;

		internal ushort RecorderId;

		internal float Hp = 100f;

		internal bool Dead;

		internal readonly HashSet<int> IgnoredProps = new HashSet<int>();

		internal Transform LeftHand;

		internal Transform RightHand;

		internal Vector3 DeathSpot;

		internal float DownTime;

		internal bool GunsDown;

		internal bool VoiceMuted;

		internal float NextVoiceCheck;

		internal Transform HeadBone;

		internal Transform HipsBone;

		internal Transform ChestBone;

		internal readonly List<CloneHitbox> Boxes = new List<CloneHitbox>();

		private readonly HashSet<int> _ignoredBodies = new HashSet<int>();

		private static DataCardReference<SurfaceDataCard> _flesh;

		private static DecalType _fleshDecal;

		private static bool _fleshSearched;

		private static readonly Dictionary<int, bool> _vehicleCache = new Dictionary<int, bool>();

		private static readonly Dictionary<int, FixedJoint> _stuckBlades = new Dictionary<int, FixedJoint>();

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

		private float _nextStabHit;

		private static readonly Dictionary<int, bool> _bladeCache = new Dictionary<int, bool>();

		private static readonly List<ValueTuple<Transform, Vector3, Vector3, float, float>> _wounds = new List<ValueTuple<Transform, Vector3, Vector3, float, float>>();

		private static readonly List<Piercing> _piercing = new List<Piercing>();

		internal void Revive()
		{
			bool dead = Dead;
			Hp = 100f;
			Dead = false;
			if (dead)
			{
				ClonesMod.OnCloneRevived(this);
			}
		}

		internal static void AddFlesh(GameObject go)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (_flesh == null || (Object)(object)go == (Object)null || (Object)(object)go.GetComponent<ImpactProperties>() != (Object)null)
			{
				return;
			}
			try
			{
				ImpactProperties obj = go.AddComponent<ImpactProperties>();
				obj.SurfaceDataCard = _flesh;
				obj.decalType = _fleshDecal;
				obj.SetupSurfaceData();
			}
			catch
			{
			}
		}

		internal static void ResetLevelCaches()
		{
			_hitCols.Clear();
			_flesh = null;
			_fleshSearched = false;
			_vehicleCache.Clear();
			_stuckBlades.Clear();
			_piercing.Clear();
		}

		internal static CloneBody Build(Avatar avatar)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Animator animator = avatar.animator;
			if ((Object)(object)animator == (Object)null || !animator.isHuman)
			{
				return null;
			}
			if (!CloneHitbox.EnsureInjected())
			{
				return null;
			}
			FindFleshSurface();
			CloneBody cloneBody = new CloneBody
			{
				Avatar = avatar,
				Anim = animator
			};
			Transform boneTransform = animator.GetBoneTransform((HumanBodyBones)0);
			Transform boneTransform2 = animator.GetBoneTransform((HumanBodyBones)10);
			Transform boneTransform3 = animator.GetBoneTransform((HumanBodyBones)5);
			float num = ((avatar.height > 0.3f) ? avatar.height : (((Object)(object)boneTransform2 != (Object)null && (Object)(object)boneTransform3 != (Object)null) ? (Vector3.Distance(boneTransform2.position, boneTransform3.position) * 1.1f) : 1.76f));
			float num2 = Mathf.Clamp(num / 1.76f, 0.3f, 4f);
			cloneBody.Height = num;
			Transform val = animator.GetBoneTransform((HumanBodyBones)8) ?? animator.GetBoneTransform((HumanBodyBones)7);
			cloneBody.HeadBone = boneTransform2;
			cloneBody.LeftHand = animator.GetBoneTransform((HumanBodyBones)17);
			cloneBody.RightHand = animator.GetBoneTransform((HumanBodyBones)18);
			cloneBody.HipsBone = boneTransform;
			cloneBody.ChestBone = val;
			Transform b = animator.GetBoneTransform((HumanBodyBones)9) ?? boneTransform2;
			cloneBody.Capsule(boneTransform, val, 0.13f * num2);
			cloneBody.Capsule(val, b, 0.14f * num2);
			cloneBody.Sphere(boneTransform2, 0.11f * num2, 0.06f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)13, (HumanBodyBones)15, 0.05f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)15, (HumanBodyBones)17, 0.045f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)14, (HumanBodyBones)16, 0.05f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)16, (HumanBodyBones)18, 0.045f * num2);
			cloneBody.Sphere(animator.GetBoneTransform((HumanBodyBones)17), 0.05f * num2, 0f);
			cloneBody.Sphere(animator.GetBoneTransform((HumanBodyBones)18), 0.05f * num2, 0f);
			cloneBody.Capsule(animator, (HumanBodyBones)1, (HumanBodyBones)3, 0.075f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)3, (HumanBodyBones)5, 0.055f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)2, (HumanBodyBones)4, 0.075f * num2);
			cloneBody.Capsule(animator, (HumanBodyBones)4, (HumanBodyBones)6, 0.055f * num2);
			cloneBody.IgnoreSelf();
			if (!ClonesMod.CollideWithYou.Value)
			{
				cloneBody.IgnorePlayer();
			}
			if (ClonesMod.OptimizeRendering.Value)
			{
				OptimizeRendering(avatar);
			}
			return cloneBody;
		}

		private void Capsule(Animator anim, HumanBodyBones from, HumanBodyBones to, float radius)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Capsule(anim.GetBoneTransform(from), anim.GetBoneTransform(to), radius);
		}

		private void Capsule(Transform a, Transform b, float radius)
		{
			//IL_0014: 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_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_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)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)a == (Object)null) && !((Object)(object)b == (Object)null))
			{
				Vector3 val = b.position - a.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (!(magnitude < 0.01f))
				{
					GameObject val2 = NewBox(a, "CloneHitbox_" + ((Object)a).name);
					val2.transform.position = (a.position + b.position) * 0.5f;
					val2.transform.rotation = Quaternion.FromToRotation(Vector3.up, val);
					CapsuleCollider val3 = val2.AddComponent<CapsuleCollider>();
					val3.direction = 1;
					val3.radius = radius;
					val3.height = magnitude + radius;
					Finish(val2, a, (Collider)(object)val3);
				}
			}
		}

		private void Sphere(Transform bone, float radius, float up)
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)bone == (Object)null))
			{
				GameObject val = NewBox(bone, "CloneHitbox_" + ((Object)bone).name);
				val.transform.position = bone.position + Vector3.up * up;
				SphereCollider val2 = val.AddComponent<SphereCollider>();
				val2.radius = radius;
				Finish(val, bone, (Collider)(object)val2);
			}
		}

		private static GameObject NewBox(Transform bone, string name)
		{
			//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_000d: 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_0023: 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_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_0054: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.SetActive(false);
			val.layer = 12;
			val.transform.SetParent(bone, false);
			float num = Mathf.Max(Mathf.Abs(bone.lossyScale.x), 0.0001f);
			val.transform.localScale = Vector3.one / num;
			return val;
		}

		private void Finish(GameObject go, Transform bone, Collider col)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody val = go.AddComponent<Rigidbody>();
			val.isKinematic = true;
			val.useGravity = false;
			val.collisionDetectionMode = (CollisionDetectionMode)0;
			val.interpolation = (RigidbodyInterpolation)0;
			if (_flesh != null)
			{
				ImpactProperties obj = go.AddComponent<ImpactProperties>();
				obj.SurfaceDataCard = _flesh;
				obj.decalType = _fleshDecal;
			}
			CloneHitbox cloneHitbox = ((Il2CppObjectBase)go.AddComponent(Il2CppType.Of<CloneHitbox>())).Cast<CloneHitbox>();
			cloneHitbox.Body = this;
			cloneHitbox.Bone = bone;
			cloneHitbox.Rb = val;
			cloneHitbox.Col = col;
			Boxes.Add(cloneHitbox);
			_hitCols.Add(((Object)col).GetInstanceID());
			go.SetActive(true);
			if (_flesh != null)
			{
				try
				{
					go.GetComponent<ImpactProperties>().SetupSurfaceData();
				}
				catch
				{
				}
			}
		}

		private static void FindFleshSurface()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (_fleshSearched)
			{
				return;
			}
			_fleshSearched = true;
			try
			{
				DataCardReference<SurfaceDataCard> val = new DataCardReference<SurfaceDataCard>("SLZ.Backlot.SurfaceDataCard.Blood");
				if (((ScannableReference)val).IsValid())
				{
					_flesh = val;
					_fleshDecal = (DecalType)0;
				}
				else
				{
					ClonesMod.Log.Msg("Game blood surface not available; using mod blood only.");
				}
			}
			catch (global::System.Exception ex)
			{
				ClonesMod.Log.Warning("Couldn't load the game's blood surface (mod blood still works): " + ex.Message);
			}
		}

		private static void OptimizeRendering(Avatar avatar)
		{
			global::System.Collections.Generic.IEnumerator<Renderer> enumerator = ((Component)avatar).GetComponentsInChildren<Renderer>(true).GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					Renderer current = enumerator.Current;
					if (!((Object)(object)current == (Object)null))
					{
						current.shadowCastingMode = (ShadowCastingMode)0;
						current.motionVectorGenerationMode = (MotionVectorGenerationMode)2;
						SkinnedMeshRenderer val = ((Il2CppObjectBase)current).TryCast<SkinnedMeshRenderer>();
						if ((Object)(object)val != (Object)null)
						{
							val.quality = (SkinQuality)2;
							val.updateWhenOffscreen = false;
							val.skinnedMotionVectors = false;
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
		}

		internal void IgnorePlayer()
		{
			RigManager rigManager = Player.RigManager;
			if (!((Object)(object)rigManager == (Object)null))
			{
				IgnoreAll(((Component)rigManager).GetComponentsInChildren<Collider>(true));
			}
		}

		internal void IgnoreVehicle(Rigidbody vehicle)
		{
			if (!((Object)(object)vehicle == (Object)null) && _ignoredBodies.Add(((Object)vehicle).GetInstanceID()))
			{
				IgnoreAll(((Component)vehicle).GetComponentsInChildren<Collider>(true));
			}
		}

		internal void IgnoreProp(GameObject prop)
		{
			if (!((Object)(object)prop == (Object)null) && IgnoredProps.Add(((Object)prop).GetInstanceID()))
			{
				IgnoreAll(prop.GetComponentsInChildren<Collider>(true));
			}
		}

		internal void IgnoreSelf()
		{
			//IL_0020: 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)
			HashSet<Transform> val = new HashSet<Transform>();
			HumanBodyBones[] array = new HumanBodyBones[10];
			RuntimeHelpers.InitializeArray((global::System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			HumanBodyBones[] array2 = (HumanBodyBones[])(object)array;
			foreach (HumanBodyBones val2 in array2)
			{
				Transform val3 = (((Object)(object)Anim != (Object)null) ? Anim.GetBoneTransform(val2) : null);
				if ((Object)(object)val3 != (Object)null)
				{
					val.Add(val3);
				}
			}
			for (int j = 0; j < Boxes.Count; j++)
			{
				for (int k = j + 1; k < Boxes.Count; k++)
				{
					CloneHitbox cloneHitbox = Boxes[j];
					CloneHitbox cloneHitbox2 = Boxes[k];
					if (!((Object)(object)cloneHitbox == (Object)null) && !((Object)(object)cloneHitbox2 == (Object)null) && !((Object)(object)cloneHitbox.Col == (Object)null) && !((Object)(object)cloneHitbox2.Col == (Object)null) && !((Object)(object)cloneHitbox.Bone == (Object)null) && !((Object)(object)cloneHitbox2.Bone == (Object)null))
					{
						bool num = val.Contains(cloneHitbox.Bone) && val.Contains(cloneHitbox2.Bone);
						bool flag = (Object)(object)cloneHitbox.Bone.parent == (Object)(object)cloneHitbox2.Bone || (Object)(object)cloneHitbox2.Bone.parent == (Object)(object)cloneHitbox.Bone || ((Object)(object)cloneHitbox.Bone.parent != (Object)null && (Object)(object)cloneHitbox.Bone.parent.parent == (Object)(object)cloneHitbox2.Bone) || ((Object)(object)cloneHitbox2.Bone.parent != (Object)null && (Object)(object)cloneHitbox2.Bone.parent.parent == (Object)(object)cloneHitbox.Bone);
						if (num || flag)
						{
							Physics.IgnoreCollision(cloneHitbox.Col, cloneHitbox2.Col, true);
						}
					}
				}
			}
		}

		private void IgnoreAll(Il2CppArrayBase<Collider> others)
		{
			//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)
			global::System.Collections.Generic.IEnumerator<Collider> enumerator = others.GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					Collider current = enumerator.Current;
					if ((Object)(object)current == (Object)null)
					{
						continue;
					}
					Enumerator<CloneHitbox> enumerator2 = Boxes.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							CloneHitbox current2 = enumerator2.Current;
							if ((Object)(object)current2 != (Object)null && (Object)(object)current2.Col != (Object)null)
							{
								Physics.IgnoreCollision(current2.Col, current, true);
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
		}

		internal static bool IsVehicle(Rigidbody rb)
		{
			if ((Object)(object)rb == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)rb).GetInstanceID();
			bool result = default(bool);
			if (_vehicleCache.TryGetValue(instanceID, ref result))
			{
				return result;
			}
			result = (Object)(object)((Component)rb).GetComponentInChildren<Seat>(true) != (Object)null || (Object)(object)((Component)rb).GetComponentInParent<Seat>() != (Object)null || (Object)(object)((Component)rb).GetComponentInChildren<Atv>(true) != (Object)null || (Object)(object)((Component)rb).GetComponentInParent<Atv>() != (Object)null;
			_vehicleCache[instanceID] = result;
			return result;
		}

		internal void OnCollision(CloneHitbox box, Collision c)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_015a: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0135: 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)
			Rigidbody rigidbody = c.rigidbody;
			if ((Object)(object)rigidbody != (Object)null && ClonesMod.IgnoreVehicles.Value && IsVehicle(rigidbody))
			{
				IgnoreVehicle(rigidbody);
				return;
			}
			Vector3 relativeVelocity = c.relativeVelocity;
			float magnitude = ((Vector3)(ref relativeVelocity)).magnitude;
			bool flag = (Object)(object)rigidbody != (Object)null && IsBlade(rigidbody);
			if (flag && magnitude < 0.8f)
			{
				Pierce(rigidbody, this);
			}
			else
			{
				if (magnitude < (flag ? 0.8f : 2f))
				{
					return;
				}
				Vector3 val;
				ContactPoint contact;
				if (c.contactCount <= 0)
				{
					val = ((Component)box).transform.position;
				}
				else
				{
					contact = c.GetContact(0);
					val = ((ContactPoint)(ref contact)).point;
				}
				Vector3 val2 = val;
				Vector3 val3;
				if (c.contactCount <= 0)
				{
					relativeVelocity = c.relativeVelocity;
					val3 = -((Vector3)(ref relativeVelocity)).normalized;
				}
				else
				{
					contact = c.GetContact(0);
					val3 = ((ContactPoint)(ref contact)).normal;
				}
				Vector3 val4 = val3;
				if (flag)
				{
					BloodFx.Hit(val2, -c.relativeVelocity, val4, Mathf.Clamp(1.4f + magnitude / 4f, 1.4f, 2.6f));
					Bleed(box, val2, val4);
					if (ClonesMod.MeleeCombat.Value && Time.time >= _nextStabHit)
					{
						_nextStabHit = Time.time + 0.4f;
						CloneDamage.Melee(box, -c.relativeVelocity, val2);
					}
					Pierce(rigidbody, this, hit: true);
				}
				else
				{
					BloodFx.Hit(val2, -c.relativeVelocity, val4, Mathf.Clamp(magnitude / 6f, 0.4f, 2f));
				}
			}
		}

		private static bool IsBlade(Rigidbody rb)
		{
			int instanceID = ((Object)rb).GetInstanceID();
			bool result = default(bool);
			if (_bladeCache.TryGetValue(instanceID, ref result))
			{
				return result;
			}
			result = (Object)(object)((Component)rb).GetComponentInParent<StabSlash>() != (Object)null || (Object)(object)((Component)rb).GetComponentInChildren<StabSlash>() != (Object)null;
			if (_bladeCache.Count > 256)
			{
				_bladeCache.Clear();
			}
			_bladeCache[instanceID] = result;
			return result;
		}

		private static void Bleed(CloneHitbox box, Vector3 at, Vector3 normal)
		{
			//IL_0027: 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_002f: 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)
			Transform transform = ((Component)box).transform;
			if (_wounds.Count > 24)
			{
				_wounds.RemoveAt(0);
			}
			_wounds.Add(new ValueTuple<Transform, Vector3, Vector3, float, float>(transform, transform.InverseTransformPoint(at), transform.InverseTransformDirection(normal), Time.time + 2.5f, Time.time + 0.12f));
		}

		private static void Pierce(Rigidbody blade, CloneBody body, bool hit = false)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<Piercing> enumerator = _piercing.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Piercing current = enumerator.Current;
					if ((Object)(object)current.Blade == (Object)(object)blade && current.Body == body)
					{
						current.Since = Time.time;
						current.Hit |= hit;
						return;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (_piercing.Count > 12)
			{
				Unpierce(_piercing[0]);
				_piercing.RemoveAt(0);
			}
			Il2CppArrayBase<Collider> componentsInChildren = ((Component)blade).GetComponentsInChildren<Collider>();
			List<Collider> val = new List<Collider>();
			global::System.Collections.Generic.IEnumerator<Collider> enumerator2 = componentsInChildren.GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator2).MoveNext())
				{
					Collider current2 = enumerator2.Current;
					if ((Object)(object)current2 != (Object)null)
					{
						val.Add(current2);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2)?.Dispose();
			}
			HashSet<global::System.IntPtr> val2 = new HashSet<global::System.IntPtr>();
			global::System.Collections.Generic.IEnumerator<Joint> enumerator3 = ((Component)blade).GetComponentsInChildren<Joint>().GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator3).MoveNext())
				{
					Joint current3 = enumerator3.Current;
					if ((Object)(object)current3 != (Object)null)
					{
						val2.Add(((Il2CppObjectBase)current3).Pointer);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator3)?.Dispose();
			}
			Piercing piercing = new Piercing
			{
				Blade = blade,
				Body = body,
				BladeCols = val.ToArray(),
				OwnJoints = val2,
				Since = Time.time,
				Hit = hit,
				Host = ((Component)blade).GetComponentInParent<InteractableHost>(),
				Slash = (((Component)blade).GetComponentInChildren<StabSlash>() ?? ((Component)blade).GetComponentInParent<StabSlash>())
			};
			Collider[] bladeCols = piercing.BladeCols;
			foreach (Collider val3 in bladeCols)
			{
				Enumerator<CloneHitbox> enumerator4 = body.Boxes.GetEnumerator();
				try
				{
					while (enumerator4.MoveNext())
					{
						CloneHitbox current4 = enumerator4.Current;
						if ((Object)(object)current4 != (Object)null && (Object)(object)current4.Col != (Object)null)
						{
							Physics.IgnoreCollision(val3, current4.Col, true);
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose();
				}
			}
			_piercing.Add(piercing);
			RemoveStabJoints(piercing);
		}

		internal static void InstallStabHook()
		{
			global::System.Type typeFromHandle = typeof(CloneBody);
			Patches.Prefix("clone-stab-enter", (MethodBase)(object)AccessTools.Method(typeof(StabSlash), "OnCollisionEnter", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "GameStabPrefix");
			Patches.Prefix("clone-stab-stay", (MethodBase)(object)AccessTools.Method(typeof(StabSlash), "OnCollisionStay", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "GameStabPrefix");
		}

		private static bool GameStabPrefix(Collision c)
		{
			if (_hitCols.Count == 0 || c == null)
			{
				return true;
			}
			try
			{
				Collider collider = c.collider;
				return (Object)(object)collider == (Object)null || !_hitCols.Contains(((Object)collider).GetInstanceID());
			}
			catch
			{
				return true;
			}
		}

		private static void UnStabGame(Piercing p)
		{
			if ((Object)(object)p.Slash == (Object)null)
			{
				return;
			}
			try
			{
				global::System.Collections.Generic.IEnumerator<StabPoint> enumerator = ((Il2CppArrayBase<StabPoint>)(object)p.Slash.stabPoints).GetEnumerator();
				try
				{
					while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
					{
						StabPoint current = enumerator.Current;
						Il2CppReferenceArray<StabJoint> val = ((current != null) ? current.stabJoints : null);
						if (val == null)
						{
							continue;
						}
						for (int num = ((Il2CppArrayBase<StabJoint>)(object)val).Count - 1; num >= 0; num--)
						{
							StabJoint val2 = ((Il2CppArrayBase<StabJoint>)(object)val)[num];
							Collider val3 = ((val2 != null) ? val2.collider : null);
							if ((Object)(object)val3 != (Object)null && _hitCols.Contains(((Object)val3).GetInstanceID()))
							{
								current.UnStab(num, false);
							}
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator)?.Dispose();
				}
			}
			catch
			{
			}
		}

		private static void RemoveStabJoints(Piercing p)
		{
			//IL_00b8: 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)
			if ((Object)(object)p.Blade == (Object)null)
			{
				return;
			}
			UnStabGame(p);
			FixedJoint val = default(FixedJoint);
			_stuckBlades.TryGetValue(((Object)p.Blade).GetInstanceID(), ref val);
			global::System.Collections.Generic.IEnumerator<Joint> enumerator = ((Component)p.Blade).GetComponentsInChildren<Joint>().GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					Joint current = enumerator.Current;
					if (!((Object)(object)current == (Object)null) && !p.OwnJoints.Contains(((Il2CppObjectBase)current).Pointer) && (!((Object)(object)val != (Object)null) || !((Object)(object)current == (Object)(object)val)))
					{
						Rigidbody connectedBody = current.connectedBody;
						if ((Object)(object)connectedBody == (Object)null || IsPart(p.Body, connectedBody))
						{
							Object.Destroy((Object)(object)current);
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
			Enumerator<CloneHitbox> enumerator2 = p.Body.Boxes.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					CloneHitbox current2 = enumerator2.Current;
					Rigidbody val2 = (((Object)(object)current2 != (Object)null && (Object)(object)current2.Col != (Object)null) ? current2.Col.attachedRigidbody : null);
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					enumerator = ((Component)val2).GetComponents<Joint>().GetEnumerator();
					try
					{
						while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
						{
							Joint current3 = enumerator.Current;
							if ((Object)(object)current3 != (Object)null && (Object)(object)current3.connectedBody == (Object)(object)p.Blade)
							{
								Object.Destroy((Object)(object)current3);
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator)?.Dispose();
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static bool IsPart(CloneBody body, Rigidbody rb)
		{
			//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)
			Enumerator<CloneHitbox> enumerator = body.Boxes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CloneHitbox current = enumerator.Current;
					if ((Object)(object)current != (Object)null && (((Object)(object)current.Rb != (Object)null && (Object)(object)current.Rb == (Object)(object)rb) || ((Object)(object)current.Col != (Object)null && (Object)(object)current.Col.attachedRigidbody == (Object)(object)rb)))
					{
						return true;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return false;
		}

		private static bool Held(Piercing p)
		{
			try
			{
				return (Object)(object)p.Host != (Object)null && p.Host.IsAttached;
			}
			catch
			{
				return false;
			}
		}

		private static void Unpierce(Piercing p)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (p.Body == null)
			{
				return;
			}
			Collider[] bladeCols = p.BladeCols;
			foreach (Collider val in bladeCols)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Enumerator<CloneHitbox> enumerator = p.Body.Boxes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CloneHitbox current = enumerator.Current;
						if ((Object)(object)current != (Object)null && (Object)(object)current.Col != (Object)null)
						{
							Physics.IgnoreCollision(val, current.Col, false);
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
		}

		private static CloneHitbox StillIn(Piercing p)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			Collider[] bladeCols = p.BladeCols;
			foreach (Collider val in bladeCols)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.bounds;
				((Bounds)(ref bounds)).Expand(0.04f);
				Enumerator<CloneHitbox> enumerator = p.Body.Boxes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CloneHitbox current = enumerator.Current;
						if ((Object)(object)current != (Object)null && (Object)(object)current.Col != (Object)null && ((Bounds)(ref bounds)).Intersects(current.Col.bounds))
						{
							return current;
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			return null;
		}

		internal static void UpdateStabs()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			//IL_0075: 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_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_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_0095: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			for (int num = _wounds.Count - 1; num >= 0; num--)
			{
				ValueTuple<Transform, Vector3, Vector3, float, float> val = _wounds[num];
				if ((Object)(object)val.Item1 == (Object)null || Time.time > val.Item4)
				{
					_wounds.RemoveAt(num);
				}
				else if (!(Time.time < val.Item5))
				{
					Vector3 point = val.Item1.TransformPoint(val.Item2);
					Vector3 val2 = val.Item1.TransformDirection(val.Item3);
					BloodFx.Hit(point, val2, val2, 0.35f);
					_wounds[num] = new ValueTuple<Transform, Vector3, Vector3, float, float>(val.Item1, val.Item2, val.Item3, val.Item4, Time.time + Random.Range(0.1f, 0.2f));
				}
			}
			FixedJoint val3 = default(FixedJoint);
			for (int num2 = _piercing.Count - 1; num2 >= 0; num2--)
			{
				Piercing piercing = _piercing[num2];
				if ((Object)(object)piercing.Blade == (Object)null || piercing.Body == null)
				{
					_piercing.RemoveAt(num2);
				}
				else
				{
					RemoveStabJoints(piercing);
					int instanceID = ((Object)piercing.Blade).GetInstanceID();
					bool flag = _stuckBlades.TryGetValue(instanceID, ref val3) && (Object)(object)val3 != (Object)null;
					bool flag2 = Held(piercing);
					CloneHitbox cloneHitbox = StillIn(piercing);
					if (!piercing.Hit && flag2 && (Object)(object)cloneHitbox != (Object)null && !piercing.Blade.isKinematic)
					{
						Vector3 velocity = piercing.Blade.velocity;
						if (((Vector3)(ref velocity)).sqrMagnitude > 0.64f)
						{
							piercing.Hit = true;
							piercing.Body.StabAt(cloneHitbox, piercing.Blade, velocity);
						}
					}
					if (flag && flag2)
					{
						Object.Destroy((Object)(object)val3);
						_stuckBlades.Remove(instanceID);
						flag = false;
					}
					else if (!flag && !flag2 && (Object)(object)cloneHitbox != (Object)null && piercing.Body.Dead && ClonesMod.StabSticking.Value)
					{
						TryStick(piercing.Blade, cloneHitbox);
						flag = _stuckBlades.TryGetValue(instanceID, ref val3) && (Object)(object)val3 != (Object)null;
					}
					if (!flag && !(Time.time - piercing.Since < 0.3f) && !((Object)(object)cloneHitbox != (Object)null))
					{
						Unpierce(piercing);
						_piercing.RemoveAt(num2);
					}
				}
			}
		}

		private void StabAt(CloneHitbox box, Rigidbody blade, Vector3 v)
		{
			//IL_0022: 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_0014: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0065: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Vector3 val = (((Object)(object)box.Col != (Object)null) ? box.Col.ClosestPoint(blade.worldCenterOfMass) : ((Component)box).transform.position);
				Vector3 val2 = -((Vector3)(ref v)).normalized;
				BloodFx.Hit(val, v, val2, Mathf.Clamp(1.4f + ((Vector3)(ref v)).magnitude / 4f, 1.4f, 2.6f));
				Bleed(box, val, val2);
				if (ClonesMod.MeleeCombat.Value && Time.time >= _nextStabHit)
				{
					_nextStabHit = Time.time + 0.4f;
					CloneDamage.Melee(box, v, val);
				}
			}
			catch
			{
			}
		}

		private static void TryStick(Rigidbody blade, CloneHitbox box)
		{
			if ((Object)(object)((Component)blade).GetComponentInParent<StabSlash>() == (Object)null && (Object)(object)((Component)blade).GetComponentInChildren<StabSlash>() == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)blade).GetInstanceID();
			FixedJoint val = default(FixedJoint);
			if ((!_stuckBlades.TryGetValue(instanceID, ref val) || !((Object)(object)val != (Object)null)) && !((Object)(object)((Component)blade).GetComponent<ConfigurableJoint>() != (Object)null))
			{
				Rigidbody val2 = (((Object)(object)box.Col != (Object)null) ? box.Col.attachedRigidbody : null);
				if (!((Object)(object)val2 == (Object)null) && !val2.isKinematic)
				{
					FixedJoint val3 = ((Component)blade).gameObject.AddComponent<FixedJoint>();
					((Joint)val3).connectedBody = val2;
					((Joint)val3).breakForce = 700f;
					((Joint)val3).breakTorque = 700f;
					((Joint)val3).enableCollision = false;
					_stuckBlades[instanceID] = val3;
				}
			}
		}

		internal void Destroy()
		{
			//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)
			Enumerator<CloneHitbox> enumerator = Boxes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CloneHitbox current = enumerator.Current;
					if ((Object)(object)current != (Object)null && (Object)(object)current.Col != (Object)null)
					{
						_hitCols.Remove(((Object)current.Col).GetInstanceID());
					}
					if ((Object)(object)current != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)current).gameObject);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Boxes.Clear();
		}
	}
	internal static class CloneDamage
	{
		internal enum Part
		{
			Head,
			Body,
			Limb
		}

		internal const float HeadDamage = 100f;

		internal const float BodyDamage = 34f;

		internal const float LimbDamage = 17f;

		private static readonly List<CloneBody> _tmp = new List<CloneBody>();

		internal static Part PartOf(CloneHitbox box)
		{
			CloneBody body = box.Body;
			if (body == null || (Object)(object)box.Bone == (Object)null)
			{
				return Part.Body;
			}
			if ((Object)(object)box.Bone == (Object)(object)body.HeadBone)
			{
				return Part.Head;
			}
			if ((Object)(object)box.Bone == (Object)(object)body.HipsBone || (Object)(object)box.Bone == (Object)(object)body.ChestBone)
			{
				return Part.Body;
			}
			return Part.Limb;
		}

		internal static void Shot(CloneHitbox box, Vector3 dir, Vector3 at, float multiplier = 1f)
		{
			//IL_0080: 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)
			if (box?.Body != null && ClonesMod.Enabled.Value)
			{
				float dmg = (100f / Mathf.Max(1f, Mathf.Round(PartOf(box) switch
				{
					Part.Head => ClonesMod.HeadShotsToKill.Value, 
					Part.Body => ClonesMod.BodyShotsToKill.Value, 
					_ => ClonesMod.LimbShotsToKill.Value, 
				})) + 0.01f) * multiplier;
				Damage(box.Body, dmg, box.Col, ((Vector3)(ref dir)).normalized * 2f, at, wholeBody: false);
			}
		}

		internal static void ShotCollider(Collider col, Vector3 dir, Vector3 at, float multiplier = 1f)
		{
			//IL_003a: 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)
			if (!((Object)(object)col == (Object)null) && CloneHitbox.Injected)
			{
				Component component = ((Component)col).GetComponent(Il2CppType.Of<CloneHitbox>());
				CloneHitbox cloneHitbox = (((Object)(object)component != (Object)null) ? ((Il2CppObjectBase)component).TryCast<CloneHitbox>() : null);
				if ((Object)(object)cloneHitbox != (Object)null)
				{
					Shot(cloneHitbox, dir, at, multiplier);
				}
			}
		}

		internal static void Blast(Vector3 at, float radius, float centerFraction)
		{
			//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_0073: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			if (!ClonesMod.Enabled.Value)
			{
				return;
			}
			try
			{
				ClonesMod.CollectBodies(_tmp);
				Enumerator<CloneBody> enumerator = _tmp.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CloneBody current = enumerator.Current;
						if (current == null || current.Dead || (Object)(object)current.HipsBone == (Object)null)
						{
							continue;
						}
						Vector3 val = (((Object)(object)current.ChestBone != (Object)null) ? current.ChestBone.position : current.HipsBone.position);
						float num = Vector3.Distance(val, at);
						if (num >= radius)
						{
							continue;
						}
						float dmg = 100f * centerFraction * Mathf.Lerp(1f, 0.25f, num / radius);
						Vector3 val2 = val - at + Vector3.up * 0.5f;
						Vector3 impulse = ((Vector3)(ref val2)).normalized * Mathf.Lerp(60f, 15f, num / radius);
						Collider part = null;
						Enumerator<CloneHitbox> enumerator2 = current.Boxes.GetEnumerator();
						try
						{
							while (enumerator2.MoveNext())
							{
								CloneHitbox current2 = enumerator2.Current;
								if ((Object)(object)current2 != (Object)null && (Object)(object)current2.Bone == (Object)(object)current.ChestBone)
								{
									part = current2.Col;
									break;
								}
							}
						}
						finally
						{
							((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
						}
						Damage(current, dmg, part, impulse, val, wholeBody: true);
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			catch (global::System.Exception ex)
			{
				ClonesMod.Log.Warning("Clone blast failed: " + ex.Message);
			}
		}

		internal static void Punch(CloneHitbox box, Vector3 dir, Vector3 at)
		{
			//IL_0049: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			if (box?.Body != null && ClonesMod.MeleeCombat.Value)
			{
				Damage(box.Body, 100f / Mathf.Max(1f, ClonesMod.PunchesToKill.Value) + 0.01f, box.Col, ((Vector3)(ref dir)).normalized * 3f, at, wholeBody: false);
			}
		}

		internal static void Melee(CloneHitbox box, Vector3 dir, Vector3 at)
		{
			//IL_0049: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			if (box?.Body != null && ClonesMod.MeleeCombat.Value)
			{
				Damage(box.Body, 100f / Mathf.Max(1f, ClonesMod.MeleeHitsToKill.Value) + 0.01f, box.Col, ((Vector3)(ref dir)).normalized * 4f, at, wholeBody: false);
			}
		}

		private static void Damage(CloneBody body, float dmg, Collider part, Vector3 impulse, Vector3 at, bool wholeBody)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (body.Dead)
			{
				Rigidbody val = (((Object)(object)part != (Object)null) ? part.attachedRigidbody : null);
				if ((Object)(object)val != (Object)null && !val.isKinematic)
				{
					val.AddForceAtPosition(impulse * 0.5f, at, (ForceMode)1);
				}
				return;
			}
			body.Hp -= dmg;
			if (!(body.Hp > 0.5f))
			{
				body.Hp = 0f;
				body.Dead = RagdollDrag.Kill(body, part, impulse, at, wholeBody);
				if (body.Dead)
				{
					ClonesMod.OnCloneDied(body);
				}
			}
		}
	}
	internal static class CloneFists
	{
		private const float MinSpeed = 3f;

		private const float Reach = 0.09f;

		private const float Cooldown = 0.35f;

		private static float _nextLeft;

		private static float _nextRight;

		internal static void Update(List<CloneBody> bodies)
		{
			if (ClonesMod.MeleeCombat.Value && bodies.Count != 0)
			{
				Check(Player.LeftHand, bodies, ref _nextLeft);
				Check(Player.RightHand, bodies, ref _nextRight);
			}
		}

		private static void Check(Hand hand, List<CloneBody> bodies, ref float next)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00de: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hand == (Object)null || Time.time < next || (Object)(object)hand.m_CurrentAttachedGO != (Object)null)
			{
				return;
			}
			Rigidbody rb = hand.rb;
			if ((Object)(object)rb == (Object)null)
			{
				return;
			}
			Vector3 velocity = rb.velocity;
			if (((Vector3)(ref velocity)).sqrMagnitude < 9f)
			{
				return;
			}
			Vector3 val = (((Object)(object)hand.palmPositionTransform != (Object)null) ? hand.palmPositionTransform.position : ((Component)hand).transform.position);
			Enumerator<CloneBody> enumerator = bodies.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (current == null || current.Dead)
					{
						continue;
					}
					Enumerator<CloneHitbox> enumerator2 = current.Boxes.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							CloneHitbox current2 = enumerator2.Current;
							if (!((Object)(object)current2 == (Object)null) && !((Object)(object)current2.Col == (Object)null))
							{
								Vector3 val2 = current2.Col.ClosestPoint(val);
								Vector3 val3 = val2 - val;
								if (!(((Vector3)(ref val3)).sqrMagnitude > 0.0081f) && (!(((Vector3)(ref val3)).sqrMagnitude > 1E-06f) || !(Vector3.Dot(velocity, val3) < 0f)))
								{
									next = Time.time + 0.35f;
									BloodFx.Hit(val2, velocity, -((Vector3)(ref velocity)).normalized, 0.5f);
									CloneDamage.Punch(current2, velocity, val2);
									return;
								}
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}
	}
	internal static class CloneHands
	{
		private class Hands
		{
			public readonly Transform[] Bone = (Transform[])(object)new Transform[30];

			public readonly Quaternion[] Rest = (Quaternion[])(object)new Quaternion[30];

			public readonly bool[] HasRest = new bool[30];

			public readonly Quaternion[] Target = (Quaternion[])(object)new Quaternion[30];

			public bool Built;

			public bool Relaxing;
		}

		private static readonly HumanBodyBones[] Fingers;

		private const int Count = 30;

		private const float Openness = 0.9f;

		private static readonly Dictionary<CloneBody, Hands> _hands;

		private static readonly List<CloneBody> _gone;

		internal static void LateUpdate(List<CloneBody> bodies)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_00ce: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f - Mathf.Exp(-8f * Time.deltaTime);
			Enumerator<CloneBody> enumerator = bodies.GetEnumerator();
			try
			{
				Hands hands = default(Hands);
				while (enumerator.MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (current == null || (Object)(object)current.Anim == (Object)null)
					{
						continue;
					}
					bool gunsDown = current.GunsDown;
					if (!_hands.TryGetValue(current, ref hands))
					{
						if (!gunsDown)
						{
							continue;
						}
						hands = (_hands[current] = new Hands());
					}
					if (!gunsDown)
					{
						hands.Relaxing = false;
						continue;
					}
					if (!hands.Built)
					{
						Build(current, hands);
						hands.Built = true;
					}
					if (!hands.Relaxing)
					{
						Aim(hands);
						hands.Relaxing = true;
					}
					for (int i = 0; i < 30; i++)
					{
						Transform val = hands.Bone[i];
						if ((Object)(object)val != (Object)null)
						{
							val.localRotation = Quaternion.Slerp(val.localRotation, hands.Target[i], num);
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (_hands.Count <= bodies.Count)
			{
				return;
			}
			_gone.Clear();
			Enumerator<CloneBody, Hands> enumerator2 = _hands.Keys.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					CloneBody current2 = enumerator2.Current;
					if (current2 == null || (Object)(object)current2.Avatar == (Object)null || !bodies.Contains(current2))
					{
						_gone.Add(current2);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			enumerator = _gone.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CloneBody current3 = enumerator.Current;
					_hands.Remove(current3);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal static void Clear()
		{
			_hands.Clear();
		}

		private static void Build(CloneBody b, Hands h)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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_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)
			for (int i = 0; i < 30; i++)
			{
				try
				{
					h.Bone[i] = b.Anim.GetBoneTransform(Fingers[i]);
				}
				catch
				{
					h.Bone[i] = null;
				}
			}
			try
			{
				global::System.Collections.Generic.IEnumerator<SkinnedMeshRenderer> enumerator = ((Component)b.Avatar).GetComponentsInChildren<SkinnedMeshRenderer>(true).GetEnumerator();
				try
				{
					int num = default(int);
					int num2 = default(int);
					while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
					{
						SkinnedMeshRenderer current = enumerator.Current;
						Mesh val = (((Object)(object)current != (Object)null) ? current.sharedMesh : null);
						Il2CppReferenceArray<Transform> val2 = (((Object)(object)current != (Object)null) ? current.bones : null);
						if ((Object)(object)val == (Object)null || val2 == null)
						{
							continue;
						}
						Il2CppStructArray<Matrix4x4> bindposes = val.bindposes;
						if (bindposes == null || ((Il2CppArrayBase<Matrix4x4>)(object)bindposes).Length == 0)
						{
							continue;
						}
						Dictionary<global::System.IntPtr, int> val3 = new Dictionary<global::System.IntPtr, int>();
						for (int j = 0; j < ((Il2CppArrayBase<Transform>)(object)val2).Length && j < ((Il2CppArrayBase<Matrix4x4>)(object)bindposes).Length; j++)
						{
							if ((Object)(object)((Il2CppArrayBase<Transform>)(object)val2)[j] != (Object)null)
							{
								val3[((Il2CppObjectBase)((Il2CppArrayBase<Transform>)(object)val2)[j]).Pointer] = j;
							}
						}
						for (int k = 0; k < 30; k++)
						{
							Transform val4 = h.Bone[k];
							if (!h.HasRest[k] && !((Object)(object)val4 == (Object)null) && !((Object)(object)val4.parent == (Object)null) && val3.TryGetValue(((Il2CppObjectBase)val4).Pointer, ref num) && val3.TryGetValue(((Il2CppObjectBase)val4.parent).Pointer, ref num2))
							{
								Matrix4x4 val5 = ((Il2CppArrayBase<Matrix4x4>)(object)bindposes)[num2];
								Matrix4x4 val6 = ((Il2CppArrayBase<Matrix4x4>)(object)bindposes)[num];
								Matrix4x4 val7 = val5 * ((Matrix4x4)(ref val6)).inverse;
								Vector3 val8 = Vector4.op_Implicit(((Matrix4x4)(ref val7)).GetColumn(2));
								Vector3 val9 = Vector4.op_Implicit(((Matrix4x4)(ref val7)).GetColumn(1));
								if (!(((Vector3)(ref val8)).sqrMagnitude < 1E-08f) && !(((Vector3)(ref val9)).sqrMagnitude < 1E-08f))
								{
									h.Rest[k] = Quaternion.LookRotation(val8, val9);
									h.HasRest[k] = true;
								}
							}
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator)?.Dispose();
				}
			}
			catch (global::System.Exception ex)
			{
				ClonesMod.Log.Msg("Clone hands: no bind pose (" + ex.Message + "), straightening instead");
			}
		}

		private static void Aim(Hands h)
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 30; i++)
			{
				Transform val = h.Bone[i];
				if (!((Object)(object)val == (Object)null))
				{
					Quaternion localRotation = val.localRotation;
					Quaternion val2 = (h.HasRest[i] ? h.Rest[i] : Straight(h, i, localRotation));
					h.Target[i] = Quaternion.Slerp(localRotation, val2, 0.9f);
				}
			}
		}

		private static Quaternion Straight(Hands h, int i, Quaternion now)
		{
			//IL_009b: 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_00a4: 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_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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0104: Unknown result type (might be due to invalid IL or missing references)
			Transform val = h.Bone[i];
			Transform parent = val.parent;
			int num = i % 3;
			Transform val2 = ((num < 2) ? h.Bone[i + 1] : ((val.childCount > 0) ? val.GetChild(0) : null));
			if ((Object)(object)val2 == (Object)null && num == 2 && (Object)(object)h.Bone[i - 1] != (Object)null)
			{
				Transform val3 = h.Bone[i - 1];
				return h.Target[i - 1] * Quaternion.Inverse(val3.localRotation) * now;
			}
			if ((Object)(object)parent == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return now;
			}
			Vector3 val4 = val.position - parent.position;
			Vector3 val5 = val2.position - val.position;
			if (((Vector3)(ref val4)).sqrMagnitude < 1E-08f || ((Vector3)(ref val5)).sqrMagnitude < 1E-08f)
			{
				return now;
			}
			Quaternion val6 = Quaternion.FromToRotation(val5, val4) * val.rotation;
			return Quaternion.Inverse(parent.rotation) * val6;
		}

		static CloneHands()
		{
			HumanBodyBones[] array = new HumanBodyBones[30];
			RuntimeHelpers.InitializeArray((global::System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Fingers = (HumanBodyBones[])(object)array;
			_hands = new Dictionary<CloneBody, Hands>();
			_gone = new List<CloneBody>();
		}
	}
	internal static class CloneMelee
	{
		private const float MinSpeed = 2.5f;

		private const float Reach = 0.07f;

		private const float MaxReach = 0.25f;

		private const float Cooldown = 0.35f;

		private const float NearBody = 3f;

		private static bool _leftTouching;

		private static bool _rightTouching;

		private static int _lastRb;

		private static float _lastHit;

		private static readonly Dictionary<int, List<ValueTuple<Collider, bool>>> _weaponCols = new Dictionary<int, List<ValueTuple<Collider, bool>>>();

		internal static void Update(List<CloneBody> bodies)
		{
			if (!ClonesMod.MeleeCombat.Value || bodies.Count == 0)
			{
				_leftTouching = (_rightTouching = false);
				return;
			}
			_leftTouching = Check(Player.LeftHand, bodies, _leftTouching);
			_rightTouching = Check(Player.RightHand, bodies, _rightTouching);
		}

		private static bool Check(Hand hand, List<CloneBody> bodies, bool wasTouching)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00f8: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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_0197: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01b6: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (((Object)(object)hand != (Object)null) ? hand.m_CurrentAttachedGO : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Rigidbody componentInParent = val.GetComponentInParent<Rigidbody>();
			if ((Object)(object)componentInParent == (Object)null || (Object)(object)((Component)componentInParent).GetComponentInParent<Gun>() != (Object)null || (Object)(object)((Component)componentInParent).GetComponentInChildren<Gun>() != (Object)null)
			{
				return false;
			}
			List<ValueTuple<Collider, bool>> val2 = WeaponColliders(componentInParent);
			if (val2.Count == 0)
			{
				return false;
			}
			Vector3 position = ((Component)hand).transform.position;
			int instanceID = ((Object)componentInParent).GetInstanceID();
			bool flag = !wasTouching && (instanceID != _lastRb || !(Time.time < _lastHit + 0.35f));
			bool result = false;
			Enumerator<CloneBody> enumerator = bodies.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (current == null || (Object)(object)current.HipsBone == (Object)null)
					{
						continue;
					}
					Vector3 val3 = current.HipsBone.position - position;
					if (((Vector3)(ref val3)).sqrMagnitude > 9f)
					{
						continue;
					}
					Enumerator<CloneHitbox> enumerator2 = current.Boxes.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							CloneHitbox current2 = enumerator2.Current;
							if ((Object)(object)current2 == (Object)null || (Object)(object)current2.Col == (Object)null || !current2.Col.enabled)
							{
								continue;
							}
							Enumerator<ValueTuple<Collider, bool>> enumerator3 = val2.GetEnumerator();
							try
							{
								while (enumerator3.MoveNext())
								{
									ValueTuple<Collider, bool> current3 = enumerator3.Current;
									Collider item = current3.Item1;
									bool item2 = current3.Item2;
									if ((Object)(object)item == (Object)null || !item.enabled)
									{
										continue;
									}
									Bounds bounds = current2.Col.bounds;
									Vector3 val4 = Closest(item, item2, ((Bounds)(ref bounds)).center);
									Vector3 val5 = current2.Col.ClosestPoint(val4);
									val4 = Closest(item, item2, val5);
									Vector3 val6 = val5 - val4;
									float magnitude = ((Vector3)(ref val6)).magnitude;
									if (magnitude > 0.25f)
									{
										continue;
									}
									if (magnitude <= 0.07f)
									{
										result = true;
				

UserLibs/WigglesBW.Fusion.dll

Decompiled 13 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using Il2CppSLZ.Marrow;
using LabFusion.Entities;
using LabFusion.Marrow.Extenders;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using UnityEngine;
using Wiggles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: InternalsVisibleTo("WigglesBW.Pack")]
[assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)]
[assembly: AssemblyVersion("2.9.4.0")]
[module: UnverifiableCode]
namespace Nuke
{
	internal static class NukeNet
	{
		internal static bool Online => NetworkInfo.HasServer;

		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<NukeLaunchMessage>();
			ModuleMessageManager.RegisterHandler<NukeExfilMessage>();
		}

		internal static void SendLaunch(bool abort, Vector3 gz, float seconds, float radius)
		{
			//IL_0027: 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_003f: 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)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<NukeLaunchMessage, NukeLaunchData>(new NukeLaunchData
				{
					Owner = PlayerIDManager.LocalSmallID,
					Abort = (byte)(abort ? 1u : 0u),
					X = gz.x,
					Y = gz.y,
					Z = gz.z,
					Seconds = seconds,
					Radius = radius
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		internal static void SendExfil(bool active, Vector3 pos, Quaternion rot, Vector3 end)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_009a: 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)
			if (NetworkInfo.HasServer)
			{
				NukeExfilData nukeExfilData = new NukeExfilData();
				nukeExfilData.Owner = PlayerIDManager.LocalSmallID;
				nukeExfilData.Active = (byte)(active ? 1u : 0u);
				nukeExfilData.P = new float[10] { pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, rot.w, end.x, end.y, end.z };
				SafeRelay.Send<NukeExfilMessage, NukeExfilData>(nukeExfilData, active ? CommonMessageRoutes.UnreliableToOtherClients : CommonMessageRoutes.ReliableToOtherClients);
			}
		}
	}
	public class NukeLaunchData : INetSerializable
	{
		public byte Owner;

		public byte Abort;

		public float X;

		public float Y;

		public float Z;

		public float Seconds;

		public float Radius;

		public int? GetSize()
		{
			return 22;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Abort);
			s.SerializeValue(ref X);
			s.SerializeValue(ref Y);
			s.SerializeValue(ref Z);
			s.SerializeValue(ref Seconds);
			s.SerializeValue(ref Radius);
		}
	}
	public class NukeLaunchMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			NukeLaunchData nukeLaunchData = ((ReceivedMessage)(ref received)).ReadData<NukeLaunchData>();
			if (nukeLaunchData.Owner != PlayerIDManager.LocalSmallID)
			{
				if (nukeLaunchData.Abort != 0)
				{
					NukeRemote.OnAbort(nukeLaunchData.Owner);
				}
				else
				{
					NukeRemote.OnLaunch(nukeLaunchData.Owner, new Vector3(nukeLaunchData.X, nukeLaunchData.Y, nukeLaunchData.Z), nukeLaunchData.Seconds, nukeLaunchData.Radius);
				}
			}
		}
	}
	public class NukeExfilData : INetSerializable
	{
		public byte Owner;

		public byte Active;

		public float[] P = new float[10];

		public int? GetSize()
		{
			return 42;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Active);
			for (int i = 0; i < P.Length; i++)
			{
				s.SerializeValue(ref P[i]);
			}
		}
	}
	public class NukeExfilMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0035: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			NukeExfilData nukeExfilData = ((ReceivedMessage)(ref received)).ReadData<NukeExfilData>();
			if (nukeExfilData.Owner != PlayerIDManager.LocalSmallID)
			{
				float[] p = nukeExfilData.P;
				NukeRemote.OnExfil(nukeExfilData.Owner, nukeExfilData.Active != 0, new Vector3(p[0], p[1], p[2]), new Quaternion(p[3], p[4], p[5], p[6]), new Vector3(p[7], p[8], p[9]));
			}
		}
	}
}
namespace Sling
{
	internal static class SlingNet
	{
		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<SlingStateMessage>();
		}

		internal static void Send(bool active, SlingStyle style, float widthCm, Vector3[] pts, int count, bool reliable)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SlingStateData slingStateData = new SlingStateData
				{
					Owner = PlayerIDManager.LocalSmallID,
					Active = (byte)(active ? 1u : 0u),
					Style = (byte)style,
					WidthMm = (byte)Mathf.Clamp(Mathf.RoundToInt(widthCm * 10f), 1, 255),
					Count = (byte)Mathf.Min(count, 12)
				};
				for (int i = 0; i < slingStateData.Count; i++)
				{
					slingStateData.P[i * 3] = pts[i].x;
					slingStateData.P[i * 3 + 1] = pts[i].y;
					slingStateData.P[i * 3 + 2] = pts[i].z;
				}
				SafeRelay.Send<SlingStateMessage, SlingStateData>(slingStateData, reliable ? CommonMessageRoutes.ReliableToOtherClients : CommonMessageRoutes.UnreliableToOtherClients);
			}
		}
	}
	public class SlingStateData : INetSerializable
	{
		public const int Size = 149;

		public byte Owner;

		public byte Active;

		public byte Style;

		public byte WidthMm;

		public byte Count;

		public float[] P = new float[36];

		public int? GetSize()
		{
			return 149;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Active);
			s.SerializeValue(ref Style);
			s.SerializeValue(ref WidthMm);
			s.SerializeValue(ref Count);
			for (int i = 0; i < P.Length; i++)
			{
				s.SerializeValue(ref P[i]);
			}
		}
	}
	public class SlingStateMessage : ModuleMessageHandler
	{
		private static readonly Vector3[] _pts = (Vector3[])(object)new Vector3[12];

		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			SlingStateData slingStateData = ((ReceivedMessage)(ref received)).ReadData<SlingStateData>();
			if (slingStateData.Owner != PlayerIDManager.LocalSmallID)
			{
				int num = Mathf.Min((int)slingStateData.Count, 12);
				for (int i = 0; i < num; i++)
				{
					_pts[i] = new Vector3(slingStateData.P[i * 3], slingStateData.P[i * 3 + 1], slingStateData.P[i * 3 + 2]);
				}
				RemoteSlings.OnState(slingStateData.Owner, slingStateData.Active != 0, (SlingStyle)slingStateData.Style, (float)(int)slingStateData.WidthMm / 1000f, _pts, num);
			}
		}
	}
}
namespace Heli
{
	internal static class HeliNet
	{
		internal const byte EvRemove = 1;

		internal const byte EvExplode = 2;

		internal const byte EvCommand = 3;

		internal const byte EvDamage = 4;

		internal static bool Online => NetworkInfo.HasServer;

		internal static byte LocalId
		{
			get
			{
				if (!NetworkInfo.HasServer)
				{
					return 0;
				}
				return PlayerIDManager.LocalSmallID;
			}
		}

		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<HeliStateMessage>();
			ModuleMessageManager.RegisterHandler<HeliEventMessage>();
		}

		internal static void SendState(Heli h)
		{
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<HeliStateMessage, HeliStateData>(new HeliStateData
				{
					Owner = h.Owner,
					Id = h.Id,
					Authority = PlayerIDManager.LocalSmallID,
					Px = h.Pos.x,
					Py = h.Pos.y,
					Pz = h.Pos.z,
					Qx = h.Rot.x,
					Qy = h.Rot.y,
					Qz = h.Rot.z,
					Qw = h.Rot.w,
					Vx = h.Vel.x,
					Vy = h.Vel.y,
					Vz = h.Vel.z,
					Rpm = (byte)Mathf.RoundToInt(Mathf.Clamp01(h.Rpm) * 255f),
					Flags = (byte)((h.EngineOn ? 1 : 0) | (h.Hover ? 2 : 0) | (h.RopesDown ? 4 : 0) | (h.Crashing ? 8 : 0)),
					Health = (byte)Mathf.Clamp(Mathf.RoundToInt(h.Health), 0, 255),
					Cx = (sbyte)Mathf.RoundToInt(h.Cyclic.x * 100f),
					Cy = (sbyte)Mathf.RoundToInt(h.Cyclic.y * 100f)
				}, CommonMessageRoutes.UnreliableToOtherClients);
			}
		}

		internal static void SendEvent(Heli h, byte ev, byte arg, Vector3 at, float amount)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<HeliEventMessage, HeliEventData>(new HeliEventData
				{
					Owner = h.Owner,
					Id = h.Id,
					Event = ev,
					Arg = arg,
					Px = at.x,
					Py = at.y,
					Pz = at.z,
					Amount = amount
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}
	}
	public class HeliStateData : INetSerializable
	{
		public byte Owner;

		public byte Id;

		public byte Authority;

		public float Px;

		public float Py;

		public float Pz;

		public float Qx;

		public float Qy;

		public float Qz;

		public float Qw;

		public float Vx;

		public float Vy;

		public float Vz;

		public byte Rpm;

		public byte Flags;

		public byte Health;

		public sbyte Cx;

		public sbyte Cy;

		public int? GetSize()
		{
			return 48;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Authority);
			s.SerializeValue(ref Px);
			s.SerializeValue(ref Py);
			s.SerializeValue(ref Pz);
			s.SerializeValue(ref Qx);
			s.SerializeValue(ref Qy);
			s.SerializeValue(ref Qz);
			s.SerializeValue(ref Qw);
			s.SerializeValue(ref Vx);
			s.SerializeValue(ref Vy);
			s.SerializeValue(ref Vz);
			s.SerializeValue(ref Rpm);
			s.SerializeValue(ref Flags);
			s.SerializeValue(ref Health);
			byte b = (byte)Cx;
			byte b2 = (byte)Cy;
			s.SerializeValue(ref b);
			s.SerializeValue(ref b2);
			Cx = (sbyte)b;
			Cy = (sbyte)b2;
		}
	}
	public class HeliStateMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0035: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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)
			HeliStateData heliStateData = ((ReceivedMessage)(ref received)).ReadData<HeliStateData>();
			if (heliStateData.Authority != PlayerIDManager.LocalSmallID)
			{
				Quaternion identity = default(Quaternion);
				((Quaternion)(ref identity))..ctor(heliStateData.Qx, heliStateData.Qy, heliStateData.Qz, heliStateData.Qw);
				if (identity.x * identity.x + identity.y * identity.y + identity.z * identity.z + identity.w * identity.w < 0.5f)
				{
					identity = Quaternion.identity;
				}
				HeliMod.OnRemoteState(heliStateData.Owner, heliStateData.Id, heliStateData.Authority, new Vector3(heliStateData.Px, heliStateData.Py, heliStateData.Pz), ((Quaternion)(ref identity)).normalized, new Vector3(heliStateData.Vx, heliStateData.Vy, heliStateData.Vz), (float)(int)heliStateData.Rpm / 255f, heliStateData.Flags, (float)(int)heliStateData.Health, new Vector2((float)heliStateData.Cx / 100f, (float)heliStateData.Cy / 100f));
			}
		}
	}
	public class HeliEventData : INetSerializable
	{
		public byte Owner;

		public byte Id;

		public byte Event;

		public byte Arg;

		public float Px;

		public float Py;

		public float Pz;

		public float Amount;

		public int? GetSize()
		{
			return 20;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Event);
			s.SerializeValue(ref Arg);
			s.SerializeValue(ref Px);
			s.SerializeValue(ref Py);
			s.SerializeValue(ref Pz);
			s.SerializeValue(ref Amount);
		}
	}
	public class HeliEventMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			HeliEventData heliEventData = ((ReceivedMessage)(ref received)).ReadData<HeliEventData>();
			HeliMod.OnRemoteEvent(heliEventData.Owner, heliEventData.Id, heliEventData.Event, heliEventData.Arg, new Vector3(heliEventData.Px, heliEventData.Py, heliEventData.Pz), heliEventData.Amount);
		}
	}
}
namespace GunJam
{
	internal static class JamNet
	{
		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<JamMessage>();
		}

		internal static void Send(Gun gun, JamType type)
		{
			//IL_0084: 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)
			if (!NetworkInfo.HasServer || (Object)(object)gun == (Object)null)
			{
				return;
			}
			NetworkEntity val = GunExtender.Cache.Get(gun);
			if (val == null)
			{
				return;
			}
			byte index = 0;
			GunExtender extender = val.GetExtender<GunExtender>();
			if (((EntityComponentArrayExtender<Gun>)(object)extender)?.Components != null)
			{
				for (int i = 0; i < ((EntityComponentArrayExtender<Gun>)(object)extender).Components.Length; i++)
				{
					if ((Object)(object)((EntityComponentArrayExtender<Gun>)(object)extender).Components[i] == (Object)(object)gun)
					{
						index = (byte)i;
						break;
					}
				}
			}
			SafeRelay.Send<JamMessage, JamData>(new JamData
			{
				Sender = PlayerIDManager.LocalSmallID,
				EntityId = val.ID,
				Index = index,
				Type = (byte)type
			}, CommonMessageRoutes.ReliableToOtherClients);
		}
	}
	public class JamData : INetSerializable
	{
		public const int Size = 5;

		public byte Sender;

		public ushort EntityId;

		public byte Index;

		public byte Type;

		public int? GetSize()
		{
			return 5;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Sender);
			s.SerializeValue(ref EntityId);
			s.SerializeValue(ref Index);
			s.SerializeValue(ref Type);
		}
	}
	public class JamMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			JamData jamData = ((ReceivedMessage)(ref received)).ReadData<JamData>();
			if (jamData.Sender != PlayerIDManager.LocalSmallID)
			{
				NetworkEntity entity = NetworkEntityManager.IDManager.RegisteredEntities.GetEntity(jamData.EntityId);
				Gun[] array = ((entity == null) ? null : ((EntityComponentArrayExtender<Gun>)(object)entity.GetExtender<GunExtender>())?.Components);
				Gun val = ((array != null && jamData.Index < array.Length) ? array[jamData.Index] : null);
				if ((Object)(object)val != (Object)null)
				{
					GunJamMod.ShowRemoteJam(val, (JamType)jamData.Type);
				}
			}
		}
	}
}
namespace Grapple
{
	internal static class GrappleNet
	{
		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<RopeStateMessage>();
		}

		internal static void Send(bool active, RopeColor color, Vector3[] points, int count, bool reliable)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected I4, but got Unknown
			//IL_009e: 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)
			if (NetworkInfo.HasServer)
			{
				RopeStateData ropeStateData = new RopeStateData
				{
					Owner = PlayerIDManager.LocalSmallID,
					Active = (byte)(active ? 1u : 0u),
					Color = (byte)(int)color
				};
				count = Mathf.Min(count, 12);
				ropeStateData.Count = (byte)count;
				for (int i = 0; i < count; i++)
				{
					ropeStateData.P[i * 3] = points[i].x;
					ropeStateData.P[i * 3 + 1] = points[i].y;
					ropeStateData.P[i * 3 + 2] = points[i].z;
				}
				SafeRelay.Send<RopeStateMessage, RopeStateData>(ropeStateData, reliable ? CommonMessageRoutes.ReliableToOtherClients : CommonMessageRoutes.UnreliableToOtherClients);
			}
		}
	}
	public class RopeStateData : INetSerializable
	{
		public const int Size = 148;

		public byte Owner;

		public byte Active;

		public byte Color;

		public byte Count;

		public float[] P = new float[36];

		public int? GetSize()
		{
			return 148;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Active);
			s.SerializeValue(ref Color);
			s.SerializeValue(ref Count);
			for (int i = 0; i < P.Length; i++)
			{
				s.SerializeValue(ref P[i]);
			}
		}
	}
	public class RopeStateMessage : ModuleMessageHandler
	{
		private static readonly Vector3[] _pts = (Vector3[])(object)new Vector3[12];

		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			RopeStateData ropeStateData = ((ReceivedMessage)(ref received)).ReadData<RopeStateData>();
			if (ropeStateData.Owner != PlayerIDManager.LocalSmallID)
			{
				int num = Mathf.Min((int)ropeStateData.Count, 12);
				for (int i = 0; i < num; i++)
				{
					_pts[i] = new Vector3(ropeStateData.P[i * 3], ropeStateData.P[i * 3 + 1], ropeStateData.P[i * 3 + 2]);
				}
				RemoteRopes.OnState(ropeStateData.Owner, ropeStateData.Active != 0, (RopeColor)ropeStateData.Color, _pts, num);
			}
		}
	}
}
namespace FpvDrone
{
	internal static class DroneNet
	{
		internal const byte EventExplode = 1;

		internal const byte EventRemove = 2;

		internal const byte EventHit = 3;

		internal static bool Online => NetworkInfo.HasServer;

		internal static byte LocalId => PlayerIDManager.LocalSmallID;

		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<DroneStateMessage>();
			ModuleMessageManager.RegisterHandler<DroneEventMessage>();
		}

		internal static void SendState(byte id, DroneType type, float size, bool motors, Vector3 pos, Quaternion rot, float throttle)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected I4, but got Unknown
			//IL_0053: 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_006d: 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_0087: 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_00a1: 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)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<DroneStateMessage, DroneStateData>(new DroneStateData
				{
					Owner = PlayerIDManager.LocalSmallID,
					Id = id,
					Type = (byte)(int)type,
					Motors = (byte)(motors ? 1u : 0u),
					Size = (byte)Mathf.Clamp(Mathf.RoundToInt(size * 20f), 1, 255),
					Px = pos.x,
					Py = pos.y,
					Pz = pos.z,
					Qx = rot.x,
					Qy = rot.y,
					Qz = rot.z,
					Qw = rot.w,
					Throttle = (byte)Mathf.RoundToInt(Mathf.Clamp01(throttle) * 255f)
				}, CommonMessageRoutes.UnreliableToOtherClients);
			}
		}

		internal static void SendEvent(byte owner, byte id, byte evt, DroneType type, WarBlast blast, Vector3 pos)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected I4, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected I4, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<DroneEventMessage, DroneEventData>(new DroneEventData
				{
					Owner = owner,
					Id = id,
					Event = evt,
					Type = (byte)(int)type,
					Blast = (byte)(int)blast,
					Px = pos.x,
					Py = pos.y,
					Pz = pos.z
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}
	}
	public class DroneStateData : INetSerializable
	{
		public const int Size_ = 34;

		public byte Owner;

		public byte Id;

		public byte Type;

		public byte Motors;

		public byte Size;

		public float Px;

		public float Py;

		public float Pz;

		public float Qx;

		public float Qy;

		public float Qz;

		public float Qw;

		public byte Throttle;

		public int? GetSize()
		{
			return 34;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Type);
			s.SerializeValue(ref Motors);
			s.SerializeValue(ref Size);
			s.SerializeValue(ref Px);
			s.SerializeValue(ref Py);
			s.SerializeValue(ref Pz);
			s.SerializeValue(ref Qx);
			s.SerializeValue(ref Qy);
			s.SerializeValue(ref Qz);
			s.SerializeValue(ref Qw);
			s.SerializeValue(ref Throttle);
		}
	}
	public class DroneStateMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0035: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_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)
			DroneStateData droneStateData = ((ReceivedMessage)(ref received)).ReadData<DroneStateData>();
			if (droneStateData.Owner != PlayerIDManager.LocalSmallID)
			{
				Quaternion identity = default(Quaternion);
				((Quaternion)(ref identity))..ctor(droneStateData.Qx, droneStateData.Qy, droneStateData.Qz, droneStateData.Qw);
				if (identity.x * identity.x + identity.y * identity.y + identity.z * identity.z + identity.w * identity.w < 0.5f)
				{
					identity = Quaternion.identity;
				}
				RemoteDrones.OnState(droneStateData.Owner, droneStateData.Id, (DroneType)droneStateData.Type, Mathf.Max((float)(int)droneStateData.Size / 20f, 0.25f), droneStateData.Motors != 0, new Vector3(droneStateData.Px, droneStateData.Py, droneStateData.Pz), ((Quaternion)(ref identity)).normalized, (float)(int)droneStateData.Throttle / 255f);
			}
		}
	}
	public class DroneEventData : INetSerializable
	{
		public const int Size = 17;

		public byte Owner;

		public byte Id;

		public byte Event;

		public byte Type;

		public byte Blast;

		public float Px;

		public float Py;

		public float Pz;

		public int? GetSize()
		{
			return 17;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Event);
			s.SerializeValue(ref Type);
			s.SerializeValue(ref Blast);
			s.SerializeValue(ref Px);
			s.SerializeValue(ref Py);
			s.SerializeValue(ref Pz);
		}
	}
	public class DroneEventMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			DroneEventData droneEventData = ((ReceivedMessage)(ref received)).ReadData<DroneEventData>();
			byte localSmallID = PlayerIDManager.LocalSmallID;
			if (droneEventData.Event == 3)
			{
				if (droneEventData.Owner == localSmallID)
				{
					DroneMod.OnRemoteShot(droneEventData.Id);
				}
			}
			else if (droneEventData.Owner != localSmallID)
			{
				if (droneEventData.Event == 1)
				{
					RemoteDrones.OnExplode(droneEventData.Owner, droneEventData.Id, (DroneType)droneEventData.Type, (WarBlast)droneEventData.Blast, new Vector3(droneEventData.Px, droneEventData.Py, droneEventData.Pz));
				}
				else
				{
					RemoteDrones.OnRemoved(droneEventData.Owner, droneEventData.Id);
				}
			}
		}
	}
}
namespace Cram
{
	internal static class CramNet
	{
		internal static bool Online => NetworkInfo.HasServer;

		internal static byte LocalId
		{
			get
			{
				if (!NetworkInfo.HasServer)
				{
					return 0;
				}
				return PlayerIDManager.LocalSmallID;
			}
		}

		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<CramStateMessage>();
			ModuleMessageManager.RegisterHandler<CramRemoveMessage>();
		}

		internal static void SendState(Cram c)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<CramStateMessage, CramStateData>(new CramStateData
				{
					Owner = c.Owner,
					Id = c.Id,
					Operator = c.Operator,
					Firing = (byte)(c.Firing ? 1u : 0u),
					Px = c.Pos.x,
					Py = c.Pos.y,
					Pz = c.Pos.z,
					BaseYaw = c.BaseYaw,
					Yaw = c.AimYaw,
					Pitch = c.AimPitch
				}, CommonMessageRoutes.UnreliableToOtherClients);
			}
		}

		internal static void SendRemove(Cram c)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<CramRemoveMessage, CramRemoveData>(new CramRemoveData
				{
					Owner = c.Owner,
					Id = c.Id
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}
	}
	public class CramStateData : INetSerializable
	{
		public byte Owner;

		public byte Id;

		public byte Operator;

		public byte Firing;

		public float Px;

		public float Py;

		public float Pz;

		public float BaseYaw;

		public float Yaw;

		public float Pitch;

		public int? GetSize()
		{
			return 28;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Id);
			s.SerializeValue(ref Operator);
			s.SerializeValue(ref Firing);
			s.SerializeValue(ref Px);
			s.SerializeValue(ref Py);
			s.SerializeValue(ref Pz);
			s.SerializeValue(ref BaseYaw);
			s.SerializeValue(ref Yaw);
			s.SerializeValue(ref Pitch);
		}
	}
	public class CramStateMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			CramStateData cramStateData = ((ReceivedMessage)(ref received)).ReadData<CramStateData>();
			CramMod.OnRemoteState(cramStateData.Owner, cramStateData.Id, cramStateData.Operator, new Vector3(cramStateData.Px, cramStateData.Py, cramStateData.Pz), cramStateData.BaseYaw, cramStateData.Yaw, cramStateData.Pitch, cramStateData.Firing != 0);
		}
	}
	public class CramRemoveData : INetSerializable
	{
		public byte Owner;

		public byte Id;

		public int? GetSize()
		{
			return 2;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Id);
		}
	}
	public class CramRemoveMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			CramRemoveData cramRemoveData = ((ReceivedMessage)(ref received)).ReadData<CramRemoveData>();
			CramMod.OnRemoteRemove(cramRemoveData.Owner, cramRemoveData.Id);
		}
	}
}
namespace Wiggles
{
	internal static class SafeRelay
	{
		private const float SettleSeconds = 4f;

		private static float _readySince = -1f;

		private static bool _warned;

		internal static bool MayControlWorld
		{
			get
			{
				if (NetworkInfo.HasServer)
				{
					return NetworkInfo.IsHost;
				}
				return true;
			}
		}

		internal static bool Ready
		{
			get
			{
				if (_readySince >= 0f)
				{
					return Time.realtimeSinceStartup - _readySince >= 4f;
				}
				return false;
			}
		}

		internal static void Update()
		{
			bool flag = false;
			try
			{
				PlayerID localID = PlayerIDManager.LocalID;
				flag = NetworkInfo.HasServer && localID != null && localID.IsValid;
			}
			catch
			{
				flag = false;
			}
			if (!flag)
			{
				_readySince = -1f;
			}
			else if (_readySince < 0f)
			{
				_readySince = Time.realtimeSinceStartup;
			}
		}

		internal static void OnLevelLoaded()
		{
			_readySince = -1f;
		}

		internal static void Send<TMsg, TData>(TData data, MessageRoute route) where TMsg : ModuleMessageHandler where TData : INetSerializable, new()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!Ready)
			{
				return;
			}
			try
			{
				MessageRelay.RelayModule<TMsg, TData>(data, route);
			}
			catch (global::System.Exception ex)
			{
				if (!_warned)
				{
					_warned = true;
					WigglesBW.Log.Warning("Fusion send failed (ignored): " + ex.Message);
					Diagnostics.Report("Fusion", "Sending a sync message failed: " + ex.Message + " (LabFusion version mismatch?)");
				}
			}
		}
	}
}
namespace AC130
{
	internal static class PlaneNet
	{
		internal static bool Online => NetworkInfo.HasServer;

		internal static byte LocalId
		{
			get
			{
				if (!NetworkInfo.HasServer)
				{
					return 0;
				}
				return PlayerIDManager.LocalSmallID;
			}
		}

		internal static void Register()
		{
			ModuleMessageManager.RegisterHandler<PlaneStateMessage>();
			ModuleMessageManager.RegisterHandler<PlaneRemoveMessage>();
			ModuleMessageManager.RegisterHandler<PlaneShotMessage>();
			ModuleMessageManager.RegisterHandler<ChuteMessage>();
			ModuleMessageManager.RegisterHandler<RpgMessage>();
			ModuleMessageManager.RegisterHandler<PlaneDownMessage>();
		}

		internal static void SendState(Plane p)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer && p != null)
			{
				SafeRelay.Send<PlaneStateMessage, PlaneStateData>(new PlaneStateData
				{
					Owner = PlayerIDManager.LocalSmallID,
					Cx = p.TargetCenter.x,
					Cy = p.TargetCenter.y,
					Cz = p.TargetCenter.z,
					Radius = p.TargetRadius,
					Altitude = p.TargetAltitude,
					Speed = p.Speed,
					Angle = p.Angle
				}, CommonMessageRoutes.UnreliableToOtherClients);
			}
		}

		internal static void SendRemove()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<PlaneRemoveMessage, PlaneRemoveData>(new PlaneRemoveData
				{
					Owner = PlayerIDManager.LocalSmallID
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		internal static void SendChute(bool open, Vector3 pos, float yaw, float roll, float amount)
		{
			//IL_0027: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				ChuteData data = new ChuteData
				{
					Owner = PlayerIDManager.LocalSmallID,
					Open = (byte)(open ? 1u : 0u),
					Px = pos.x,
					Py = pos.y,
					Pz = pos.z,
					Yaw = yaw,
					Roll = roll,
					Amount = (byte)Mathf.RoundToInt(Mathf.Clamp01(amount) * 255f)
				};
				MessageRoute route = (open ? CommonMessageRoutes.UnreliableToOtherClients : CommonMessageRoutes.ReliableToOtherClients);
				SafeRelay.Send<ChuteMessage, ChuteData>(data, route);
			}
		}

		internal static void SendRpg(Vector3 origin, Vector3 dir, byte target, byte heliOwner, byte heliId)
		{
			//IL_002f: 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_0047: 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_005f: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<RpgMessage, RpgData>(new RpgData
				{
					Shooter = PlayerIDManager.LocalSmallID,
					Target = target,
					HeliOwner = heliOwner,
					HeliId = heliId,
					Ox = origin.x,
					Oy = origin.y,
					Oz = origin.z,
					Dx = dir.x,
					Dy = dir.y,
					Dz = dir.z
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		internal static void SendDown(byte owner)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer)
			{
				SafeRelay.Send<PlaneDownMessage, PlaneRemoveData>(new PlaneRemoveData
				{
					Owner = owner
				}, CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		internal static void SendShot(Weapon w, Vector3 origin, Vector3 dir)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected I4, but got Unknown
			//IL_0020: 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_0038: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			if (NetworkInfo.HasServer)
			{
				PlaneShotData data = new PlaneShotData
				{
					Shooter = PlayerIDManager.LocalSmallID,
					Weapon = (byte)(int)w,
					Ox = origin.x,
					Oy = origin.y,
					Oz = origin.z,
					Dx = dir.x,
					Dy = dir.y,
					Dz = dir.z
				};
				MessageRoute route = (((int)w == 0) ? CommonMessageRoutes.UnreliableToOtherClients : CommonMessageRoutes.ReliableToOtherClients);
				SafeRelay.Send<PlaneShotMessage, PlaneShotData>(data, route);
			}
		}
	}
	public class PlaneStateData : INetSerializable
	{
		public byte Owner;

		public float Cx;

		public float Cy;

		public float Cz;

		public float Radius;

		public float Altitude;

		public float Speed;

		public float Angle;

		public int? GetSize()
		{
			return 29;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Cx);
			s.SerializeValue(ref Cy);
			s.SerializeValue(ref Cz);
			s.SerializeValue(ref Radius);
			s.SerializeValue(ref Altitude);
			s.SerializeValue(ref Speed);
			s.SerializeValue(ref Angle);
		}
	}
	public class PlaneStateMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			PlaneStateData planeStateData = ((ReceivedMessage)(ref received)).ReadData<PlaneStateData>();
			if (planeStateData.Owner != PlayerIDManager.LocalSmallID)
			{
				Planes.OnRemoteState(planeStateData.Owner, new Vector3(planeStateData.Cx, planeStateData.Cy, planeStateData.Cz), planeStateData.Radius, planeStateData.Altitude, planeStateData.Speed, planeStateData.Angle);
			}
		}
	}
	public class PlaneRemoveData : INetSerializable
	{
		public byte Owner;

		public int? GetSize()
		{
			return 1;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
		}
	}
	public class PlaneRemoveMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			PlaneRemoveData planeRemoveData = ((ReceivedMessage)(ref received)).ReadData<PlaneRemoveData>();
			if (planeRemoveData.Owner != PlayerIDManager.LocalSmallID)
			{
				Planes.OnRemoteRemoved(planeRemoveData.Owner);
			}
		}
	}
	public class ChuteData : INetSerializable
	{
		public byte Owner;

		public byte Open;

		public byte Amount;

		public float Px;

		public float Py;

		public float Pz;

		public float Yaw;

		public float Roll;

		public int? GetSize()
		{
			return 23;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Owner);
			s.SerializeValue(ref Open);
			s.SerializeValue(ref Amount);
			s.SerializeValue(ref Px);
			s.SerializeValue(ref Py);
			s.SerializeValue(ref Pz);
			s.SerializeValue(ref Yaw);
			s.SerializeValue(ref Roll);
		}
	}
	public class ChuteMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			ChuteData chuteData = ((ReceivedMessage)(ref received)).ReadData<ChuteData>();
			if (chuteData.Owner != PlayerIDManager.LocalSmallID)
			{
				if (chuteData.Open == 0)
				{
					RemoteChutes.OnClosed((int)chuteData.Owner);
				}
				else
				{
					RemoteChutes.OnState((int)chuteData.Owner, new Vector3(chuteData.Px, chuteData.Py, chuteData.Pz), chuteData.Yaw, chuteData.Roll, (float)(int)chuteData.Amount / 255f, false);
				}
			}
		}
	}
	public class RpgData : INetSerializable
	{
		public byte Shooter;

		public byte Target;

		public byte HeliOwner;

		public byte HeliId;

		public float Ox;

		public float Oy;

		public float Oz;

		public float Dx;

		public float Dy;

		public float Dz;

		public int? GetSize()
		{
			return 28;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Shooter);
			s.SerializeValue(ref Target);
			s.SerializeValue(ref HeliOwner);
			s.SerializeValue(ref HeliId);
			s.SerializeValue(ref Ox);
			s.SerializeValue(ref Oy);
			s.SerializeValue(ref Oz);
			s.SerializeValue(ref Dx);
			s.SerializeValue(ref Dy);
			s.SerializeValue(ref Dz);
		}
	}
	public class RpgMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			RpgData rpgData = ((ReceivedMessage)(ref received)).ReadData<RpgData>();
			if (rpgData.Shooter != PlayerIDManager.LocalSmallID)
			{
				AC130Mod.OnRemoteRpg(new Vector3(rpgData.Ox, rpgData.Oy, rpgData.Oz), new Vector3(rpgData.Dx, rpgData.Dy, rpgData.Dz), rpgData.Target, rpgData.HeliOwner, rpgData.HeliId);
			}
		}
	}
	public class PlaneDownMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			AC130Mod.OnRemoteDown(((ReceivedMessage)(ref received)).ReadData<PlaneRemoveData>().Owner);
		}
	}
	public class PlaneShotData : INetSerializable
	{
		public byte Shooter;

		public byte Weapon;

		public float Ox;

		public float Oy;

		public float Oz;

		public float Dx;

		public float Dy;

		public float Dz;

		public int? GetSize()
		{
			return 26;
		}

		public void Serialize(INetSerializer s)
		{
			s.SerializeValue(ref Shooter);
			s.SerializeValue(ref Weapon);
			s.SerializeValue(ref Ox);
			s.SerializeValue(ref Oy);
			s.SerializeValue(ref Oz);
			s.SerializeValue(ref Dx);
			s.SerializeValue(ref Dy);
			s.SerializeValue(ref Dz);
		}
	}
	public class PlaneShotMessage : ModuleMessageHandler
	{
		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0037: 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)
			PlaneShotData planeShotData = ((ReceivedMessage)(ref received)).ReadData<PlaneShotData>();
			if (planeShotData.Shooter != PlayerIDManager.LocalSmallID && planeShotData.Weapon <= 2)
			{
				AC130Mod.OnRemoteShot((Weapon)planeShotData.Weapon, new Vector3(planeShotData.Ox, planeShotData.Oy, planeShotData.Oz), new Vector3(planeShotData.Dx, planeShotData.Dy, planeShotData.Dz));
			}
		}
	}
}

UserLibs/WigglesBW.Timeline.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using AC130;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.VRMK;
using Timeline;
using Timeline.Serialization.Binary;
using Timeline.Serialization.Registry;
using Timeline.WorldRecording;
using Timeline.WorldRecording.Recorders;
using UnityEngine;
using Wiggles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: InternalsVisibleTo("WigglesBW.Pack")]
[assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)]
[assembly: AssemblyVersion("2.9.4.0")]
[module: UnverifiableCode]
namespace Nuke
{
	internal static class NukeTimeline
	{
		internal const byte RecorderId = 240;

		private static bool _wasRecording;

		private static NukeRecorder _current;

		internal static void Register()
		{
			FieldInfo field = typeof(SerializableRegistry).GetField("recorderTypeRegistry", (BindingFlags)40);
			if (((field != null) ? field.GetValue((object)null) : null) is Dictionary<byte, global::System.Type> val)
			{
				val[(byte)240] = typeof(NukeRecorder);
			}
		}

		internal static void Tick(bool active)
		{
			if (!WorldPlayer.recording)
			{
				_current = null;
				_wasRecording = false;
				return;
			}
			if (!_wasRecording)
			{
				_current = null;
			}
			_wasRecording = true;
			if (_current == null && active)
			{
				WorldPlayer val = ((TimelineMainClass.timelineHolder != null) ? TimelineMainClass.timelineHolder.worldPlayer : WorldPlayer.Instance);
				if (val != null)
				{
					Register();
					NukeRecorder nukeRecorder = new NukeRecorder();
					((ObjectRecorder)nukeRecorder).OnInitializedRecording((Object)null);
					((ObjectRecorder)nukeRecorder).recording = true;
					((ObjectRecorder)nukeRecorder).initTime = WorldPlayer.playHead;
					val.AddRecorderToRecord((ObjectRecorder)(object)nukeRecorder);
					_current = nukeRecorder;
				}
			}
		}
	}
	public class NukeRecorder : ObjectRecorder
	{
		private readonly List<ValueTuple<float, Vector3, float>> _nukes = new List<ValueTuple<float, Vector3, float>>();

		private readonly List<float> _t = new List<float>();

		private readonly List<Vector3> _pos = new List<Vector3>();

		private readonly List<Vector3> _end = new List<Vector3>();

		private readonly List<Quaternion> _rot = new List<Quaternion>();

		private readonly List<byte> _on = new List<byte>();

		private float _lastCapture = -3.4028235E+38f;

		private float _lastPlay;

		private int _lastLaunch = -1;

		private int _armedFor = -1;

		private readonly HashSet<int> _blown = new HashSet<int>();

		private NukeGhost _ghost;

		public override byte SerializeableID => 240;

		public override string GetName()
		{
			return "Nuke";
		}

		public override void OnInitializedRecording(Object obj)
		{
			_nukes.Clear();
			_t.Clear();
			_pos.Clear();
			_end.Clear();
			_rot.Clear();
			_on.Clear();
			Vector3 val = default(Vector3);
			float num = default(float);
			float num2 = default(float);
			_lastLaunch = NukeMod.LaunchId - (NukeMod.Armed(ref val, ref num, ref num2) ? 1 : 0);
		}

		public override void Capture(float time)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			float num = default(float);
			float num2 = default(float);
			if (NukeMod.LaunchId != _lastLaunch && NukeMod.Armed(ref val, ref num, ref num2))
			{
				_lastLaunch = NukeMod.LaunchId;
				_nukes.Add(new ValueTuple<float, Vector3, float>(time + num, val, num2));
			}
			if (!(time - _lastCapture < 0.05f))
			{
				_lastCapture = time;
				Vector3 val2 = default(Vector3);
				Quaternion val3 = default(Quaternion);
				Vector3 val4 = default(Vector3);
				bool flag = Exfil.State(ref val2, ref val3, ref val4);
				if (flag || (_on.Count != 0 && _on[_on.Count - 1] != 0))
				{
					_t.Add(time);
					_pos.Add(val2);
					_rot.Add(val3);
					_end.Add(val4);
					_on.Add((byte)(flag ? 1u : 0u));
				}
			}
		}

		public override void OnRecordingCompleted()
		{
		}

		public override void OnInitializedPlayback()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			if (_ghost == null)
			{
				_ghost = new NukeGhost();
			}
			_blown.Clear();
			_armedFor = -1;
		}

		public override void Playback(float time)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			if (_ghost == null)
			{
				((ObjectRecorder)this).OnInitializedPlayback();
			}
			float num = Mathf.Clamp(Mathf.Abs(time - _lastPlay), 0f, 0.1f);
			bool flag = Mathf.Abs(time - _lastPlay) > 0.5f;
			_lastPlay = time;
			for (int i = 0; i < _nukes.Count; i++)
			{
				ValueTuple<float, Vector3, float> val = _nukes[i];
				float num2 = val.Item1 - time;
				if (num2 > 0f && num2 <= 6f)
				{
					if (_armedFor != i)
					{
						NukeFx.Arm(val.Item2);
						_armedFor = i;
					}
					_blown.Remove(i);
					NukeFx.Countdown(num2);
				}
				else if (num2 <= 0f && num2 > -1.5f && !_blown.Contains(i))
				{
					_blown.Add(i);
					_armedFor = -1;
					NukeFx.Detonate(val.Item2, val.Item3, !NukeMod.Online);
				}
				else if (num2 > 6f)
				{
					_blown.Remove(i);
					if (_armedFor == i)
					{
						NukeFx.ClearArmed();
						_armedFor = -1;
					}
				}
			}
			int num3 = Frame(time);
			if (num3 < 0 || _on[num3] == 0 || (num3 + 1 < _t.Count && _t[num3 + 1] - _t[num3] > 0.5f))
			{
				_ghost.Hide();
				return;
			}
			int num4 = Math.Min(num3 + 1, _t.Count - 1);
			float num5 = ((num4 > num3 && _t[num4] > _t[num3]) ? Mathf.Clamp01((time - _t[num3]) / (_t[num4] - _t[num3])) : 0f);
			if (_on[num4] == 0)
			{
				num5 = 0f;
			}
			_ghost.Set(Vector3.Lerp(_pos[num3], _pos[num4], num5), Quaternion.Slerp(_rot[num3], _rot[num4], num5), Vector3.Lerp(_end[num3], _end[num4], num5), flag);
			_ghost.Update(num);
		}

		private int Frame(float time)
		{
			int num = 0;
			int num2 = _t.Count - 1;
			int result = -1;
			while (num <= num2)
			{
				int num3 = (num + num2) / 2;
				if (_t[num3] <= time)
				{
					result = num3;
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return result;
		}

		public override void OnPlaybackCompleted()
		{
			NukeGhost ghost = _ghost;
			if (ghost != null)
			{
				ghost.Hide();
			}
			_armedFor = -1;
		}

		public override void OnHide(bool hide)
		{
			if (hide)
			{
				NukeGhost ghost = _ghost;
				if (ghost != null)
				{
					ghost.Hide();
				}
			}
		}

		public override int GetSize()
		{
			return ((ObjectRecorder)this).GetSize() + 4 + _nukes.Count * 20 + 4 + _t.Count * 45;
		}

		public override void WriteToStream(BinaryStream stream)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002f: 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_0047: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).WriteToStream(stream);
			stream.WriteInt32(_nukes.Count);
			Enumerator<ValueTuple<float, Vector3, float>> enumerator = _nukes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ValueTuple<float, Vector3, float> current = enumerator.Current;
					stream.WriteSingle(current.Item1);
					stream.WriteVector3(current.Item2);
					stream.WriteSingle(current.Item3);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			stream.WriteInt32(_t.Count);
			for (int i = 0; i < _t.Count; i++)
			{
				stream.WriteSingle(_t[i]);
				stream.WriteVector3(_pos[i]);
				Quaternion val = _rot[i];
				stream.WriteSingle(val.x);
				stream.WriteSingle(val.y);
				stream.WriteSingle(val.z);
				stream.WriteSingle(val.w);
				stream.WriteVector3(_end[i]);
				stream.WriteByte(_on[i]);
			}
		}

		public override void ReadFromStream(BinaryStream stream)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_00a8: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).ReadFromStream(stream);
			_nukes.Clear();
			int num = stream.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				float num2 = stream.ReadSingle();
				Vector3 val = stream.ReadVector3();
				_nukes.Add(new ValueTuple<float, Vector3, float>(num2, val, stream.ReadSingle()));
			}
			_t.Clear();
			_pos.Clear();
			_end.Clear();
			_rot.Clear();
			_on.Clear();
			int num3 = stream.ReadInt32();
			for (int j = 0; j < num3; j++)
			{
				_t.Add(stream.ReadSingle());
				_pos.Add(stream.ReadVector3());
				_rot.Add(new Quaternion(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()));
				_end.Add(stream.ReadVector3());
				_on.Add(stream.ReadByte());
			}
		}
	}
}
namespace TimelineClones
{
	internal static class RagdollTimeline
	{
		internal const byte RecorderId = 234;

		private static bool _wasRecording;

		private static RagdollRecorder _current;

		internal static readonly List<RagdollRecorder> Playing = new List<RagdollRecorder>();

		private static FieldInfo _voiceField;

		private static readonly Dictionary<ushort, float> LiveStarts = new Dictionary<ushort, float>();

		internal static float PlayHead => WorldPlayer.playHead;

		internal static void Install(Harmony harmony)
		{
			FieldInfo field = typeof(SerializableRegistry).GetField("recorderTypeRegistry", (BindingFlags)40);
			if (((field != null) ? field.GetValue((object)null) : null) is Dictionary<byte, global::System.Type> val)
			{
				val[(byte)234] = typeof(RagdollRecorder);
			}
			MethodInfo val2 = AccessTools.Method(typeof(RigmanagerRecorder), "Playback", (global::System.Type[])null, (global::System.Type[])null);
			Patches.Prefix("clones-ragdoll-playback", (MethodBase)(object)val2, typeof(RagdollTimeline), "PlaybackPrefix");
			CloneGuns.Install(harmony);
		}

		private static bool PlaybackPrefix(RigmanagerRecorder __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ushort recorderID = ((ObjectRecorder)__instance).recorderID;
				if (RagdollDrag.IsLive(recorderID))
				{
					return false;
				}
				float playHead = WorldPlayer.playHead;
				Enumerator<RagdollRecorder> enumerator = Playing.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						if (enumerator.Current.Owns(recorderID, playHead))
						{
							return false;
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			catch
			{
			}
			return true;
		}

		internal static void SetVoiceMuted(ushort id, bool muted)
		{
			WorldPlayer instance = WorldPlayer.Instance;
			if (instance == null)
			{
				return;
			}
			ObjectRecorder objectRecorder = instance.GetObjectRecorder(id);
			RigmanagerRecorder val = (RigmanagerRecorder)(object)((objectRecorder is RigmanagerRecorder) ? objectRecorder : null);
			if (val != null)
			{
				if (_voiceField == null)
				{
					_voiceField = typeof(RigmanagerRecorder).GetField("voiceSource", (BindingFlags)52);
				}
				FieldInfo voiceField = _voiceField;
				object obj = ((voiceField != null) ? voiceField.GetValue((object)val) : null);
				AudioSource val2 = (AudioSource)((obj is AudioSource) ? obj : null);
				if ((Object)(object)val2 != (Object)null && val2.mute != muted)
				{
					val2.mute = muted;
				}
			}
		}

		internal static bool IsRagdolled(ushort id)
		{
			//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)
			if (RagdollDrag.IsLive(id))
			{
				return true;
			}
			float playHead = WorldPlayer.playHead;
			Enumerator<RagdollRecorder> enumerator = Playing.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.Owns(id, playHead))
					{
						return true;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return false;
		}

		internal static void Tick()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_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)
			if (!WorldPlayer.recording)
			{
				_current = null;
				_wasRecording = false;
			}
			else
			{
				if (!_wasRecording)
				{
					_current = null;
				}
				_wasRecording = true;
				if (_current == null && RagdollDrag.LiveById.Count > 0)
				{
					WorldPlayer val = ((TimelineMainClass.timelineHolder != null) ? TimelineMainClass.timelineHolder.worldPlayer : WorldPlayer.Instance);
					if (val != null)
					{
						RagdollRecorder ragdollRecorder = new RagdollRecorder();
						((ObjectRecorder)ragdollRecorder).OnInitializedRecording((Object)null);
						((ObjectRecorder)ragdollRecorder).recording = true;
						((ObjectRecorder)ragdollRecorder).initTime = WorldPlayer.playHead;
						val.AddRecorderToRecord((ObjectRecorder)(object)ragdollRecorder);
						_current = ragdollRecorder;
					}
				}
			}
			if (LiveStarts.Count == 0 && RagdollDrag.LiveById.Count == 0)
			{
				return;
			}
			Enumerator<KeyValuePair<ushort, float>> enumerator = new List<KeyValuePair<ushort, float>>((global::System.Collections.Generic.IEnumerable<KeyValuePair<ushort, float>>)LiveStarts).GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<ushort, float> current = enumerator.Current;
					if (WorldPlayer.playHead < current.Value - 0.1f)
					{
						RagdollDrag.Revert(current.Key);
						LiveStarts.Remove(current.Key);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<ushort, Live> enumerator2 = RagdollDrag.LiveById.Keys.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					ushort current2 = enumerator2.Current;
					if (!LiveStarts.ContainsKey(current2))
					{
						LiveStarts[current2] = WorldPlayer.playHead;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal static void Clear()
		{
			LiveStarts.Clear();
		}
	}
	public class RagdollRecorder : ObjectRecorder
	{
		private class Track
		{
			public readonly List<float> Times = new List<float>();

			public readonly List<Vector3> HipPos = new List<Vector3>();

			public readonly List<Quaternion> Rots = new List<Quaternion>();
		}

		private const int B = 11;

		private readonly Dictionary<ushort, Track> _tracks = new Dictionary<ushort, Track>();

		private float _lastCapture = -3.4028235E+38f;

		private readonly Transform[] _bones = (Transform[])(object)new Transform[11];

		public override byte SerializeableID => 234;

		public override string GetName()
		{
			return "Ragdoll Drags";
		}

		internal bool Owns(ushort id, float t)
		{
			Track track = default(Track);
			if (_tracks.TryGetValue(id, ref track) && track.Times.Count > 0)
			{
				return t >= track.Times[0];
			}
			return false;
		}

		public override void OnInitializedRecording(Object obj)
		{
			_tracks.Clear();
		}

		public override void Capture(float time)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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)
			if (time - _lastCapture < 1f / 30f)
			{
				return;
			}
			_lastCapture = time;
			Enumerator<ushort, Live> enumerator = RagdollDrag.LiveById.Values.GetEnumerator();
			try
			{
				Track track = default(Track);
				while (enumerator.MoveNext())
				{
					Live current = enumerator.Current;
					if (!((Object)(object)current.T[0] == (Object)null))
					{
						if (!_tracks.TryGetValue(current.Id, ref track))
						{
							track = (_tracks[current.Id] = new Track());
						}
						track.Times.Add(time);
						track.HipPos.Add(current.T[0].position);
						track.Rots.Add(current.T[0].rotation);
						for (int i = 1; i < 11; i++)
						{
							track.Rots.Add(((Object)(object)current.T[i] != (Object)null) ? current.T[i].localRotation : Quaternion.identity);
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void OnRecordingCompleted()
		{
		}

		public override void OnInitializedPlayback()
		{
			if (!RagdollTimeline.Playing.Contains(this))
			{
				RagdollTimeline.Playing.Add(this);
			}
		}

		public override void Playback(float time)
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: 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_023d: Unknown result type (might be due to invalid IL or missing references)
			if (!RagdollTimeline.Playing.Contains(this))
			{
				RagdollTimeline.Playing.Add(this);
			}
			WorldPlayer instance = WorldPlayer.Instance;
			if (instance == null)
			{
				return;
			}
			Enumerator<ushort, Track> enumerator = _tracks.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<ushort, Track> current = enumerator.Current;
					Track value = current.Value;
					if (value.Times.Count == 0 || time < value.Times[0] || RagdollDrag.IsLive(current.Key))
					{
						continue;
					}
					ObjectRecorder objectRecorder = instance.GetObjectRecorder(current.Key);
					Avatar val = ((RigmanagerRecorder)(((objectRecorder is RigmanagerRecorder) ? objectRecorder : null)?)).currentPlaybackAvatar;
					Animator val2 = (((Object)(object)val != (Object)null) ? val.animator : null);
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					for (int i = 0; i < 11; i++)
					{
						_bones[i] = val2.GetBoneTransform(RagdollDrag.Bones[i]);
					}
					if ((Object)(object)_bones[1] == (Object)null)
					{
						_bones[1] = val2.GetBoneTransform((HumanBodyBones)7);
					}
					if ((Object)(object)_bones[0] == (Object)null)
					{
						continue;
					}
					int num = 0;
					int num2 = value.Times.Count - 1;
					while (num < num2)
					{
						int num3 = (num + num2 + 1) / 2;
						if (value.Times[num3] <= time)
						{
							num = num3;
						}
						else
						{
							num2 = num3 - 1;
						}
					}
					int num4 = Mathf.Min(num + 1, value.Times.Count - 1);
					float num5 = ((num4 == num) ? 0f : Mathf.InverseLerp(value.Times[num], value.Times[num4], time));
					_bones[0].SetPositionAndRotation(Vector3.Lerp(value.HipPos[num], value.HipPos[num4], num5), Quaternion.Slerp(value.Rots[num * 11], value.Rots[num4 * 11], num5));
					for (int j = 1; j < 11; j++)
					{
						if ((Object)(object)_bones[j] != (Object)null)
						{
							_bones[j].localRotation = Quaternion.Slerp(value.Rots[num * 11 + j], value.Rots[num4 * 11 + j], num5);
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void OnPlaybackCompleted()
		{
			RagdollTimeline.Playing.Remove(this);
		}

		public override void OnHide(bool hide)
		{
		}

		public override int GetSize()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			int num = ((ObjectRecorder)this).GetSize() + 4;
			Enumerator<ushort, Track> enumerator = _tracks.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Track current = enumerator.Current;
					num += 6 + current.Times.Count * 192;
				}
				return num;
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void WriteToStream(BinaryStream s)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			((ObjectRecorder)this).WriteToStream(s);
			s.WriteInt32(_tracks.Count);
			Enumerator<ushort, Track> enumerator = _tracks.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<ushort, Track> current = enumerator.Current;
					Track value = current.Value;
					s.WriteUInt16(current.Key);
					s.WriteInt32(value.Times.Count);
					for (int i = 0; i < value.Times.Count; i++)
					{
						s.WriteSingle(value.Times[i]);
						s.WriteVector3(value.HipPos[i]);
						for (int j = 0; j < 11; j++)
						{
							s.WriteQuaternion(value.Rots[i * 11 + j]);
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void ReadFromStream(BinaryStream s)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).ReadFromStream(s);
			_tracks.Clear();
			int num = s.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				ushort num2 = s.ReadUInt16();
				Track track = new Track();
				int num3 = s.ReadInt32();
				for (int j = 0; j < num3; j++)
				{
					track.Times.Add(s.ReadSingle());
					track.HipPos.Add(s.ReadVector3());
					for (int k = 0; k < 11; k++)
					{
						track.Rots.Add(s.ReadQuaternion());
					}
				}
				_tracks[num2] = track;
			}
		}
	}
	internal static class BloodTimeline
	{
		internal const byte RecorderId = 238;

		private static bool _wasRecording;

		private static BloodRecorder _current;

		internal static void Register()
		{
			FieldInfo field = typeof(SerializableRegistry).GetField("recorderTypeRegistry", (BindingFlags)40);
			if (((field != null) ? field.GetValue((object)null) : null) is Dictionary<byte, global::System.Type> val)
			{
				val[(byte)238] = typeof(BloodRecorder);
			}
		}

		internal static void Tick()
		{
			if (!WorldPlayer.recording)
			{
				_current = null;
				_wasRecording = false;
				return;
			}
			if (!_wasRecording)
			{
				_current = null;
			}
			_wasRecording = true;
		}

		internal static void Record(Vector3 point, Vector3 dir, Vector3 normal, float amount)
		{
			//IL_0075: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!WorldPlayer.recording)
			{
				return;
			}
			if (_current == null)
			{
				WorldPlayer val = ((TimelineMainClass.timelineHolder != null) ? TimelineMainClass.timelineHolder.worldPlayer : WorldPlayer.Instance);
				if (val == null)
				{
					return;
				}
				Register();
				_current = new BloodRecorder();
				((ObjectRecorder)_current).OnInitializedRecording((Object)null);
				((ObjectRecorder)_current).recording = true;
				((ObjectRecorder)_current).initTime = WorldPlayer.playHead;
				val.AddRecorderToRecord((ObjectRecorder)(object)_current);
			}
			_current.Add(WorldPlayer.playHead, point, dir, normal, amount);
		}
	}
	public class BloodRecorder : ObjectRecorder
	{
		private struct Hit
		{
			public float Time;

			public float Amount;

			public Vector3 Point;

			public Vector3 Dir;

			public Vector3 Normal;
		}

		private readonly List<Hit> _hits = new List<Hit>();

		private float _last = -3.4028235E+38f;

		public override byte SerializeableID => 238;

		public override string GetName()
		{
			return "Clone Blood";
		}

		internal void Add(float time, Vector3 p, Vector3 d, Vector3 n, float a)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			_hits.Add(new Hit
			{
				Time = time,
				Point = p,
				Dir = d,
				Normal = n,
				Amount = a
			});
		}

		public override void OnInitializedRecording(Object obj)
		{
			_hits.Clear();
		}

		public override void Capture(float time)
		{
		}

		public override void OnRecordingCompleted()
		{
		}

		public override void OnInitializedPlayback()
		{
			_last = -3.4028235E+38f;
		}

		public override void Playback(float time)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (_last == -3.4028235E+38f || time < _last || time - _last > 1f)
			{
				_last = time;
				return;
			}
			Enumerator<Hit> enumerator = _hits.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Hit current = enumerator.Current;
					if (!(current.Time <= _last) && !(current.Time > time))
					{
						BloodFx.Replaying = true;
						try
						{
							BloodFx.Hit(current.Point, current.Dir, current.Normal, current.Amount);
						}
						finally
						{
							BloodFx.Replaying = false;
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			_last = time;
		}

		public override void OnPlaybackCompleted()
		{
			_last = -3.4028235E+38f;
		}

		public override void OnHide(bool hide)
		{
			if (hide)
			{
				_last = -3.4028235E+38f;
			}
		}

		public override int GetSize()
		{
			return ((ObjectRecorder)this).GetSize() + 4 + _hits.Count * 44;
		}

		public override void WriteToStream(BinaryStream s)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).WriteToStream(s);
			s.WriteInt32(_hits.Count);
			Enumerator<Hit> enumerator = _hits.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Hit current = enumerator.Current;
					s.WriteSingle(current.Time);
					s.WriteVector3(current.Point);
					s.WriteVector3(current.Dir);
					s.WriteVector3(current.Normal);
					s.WriteSingle(current.Amount);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void ReadFromStream(BinaryStream s)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			((ObjectRecorder)this).ReadFromStream(s);
			_hits.Clear();
			int num = s.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				_hits.Add(new Hit
				{
					Time = s.ReadSingle(),
					Point = s.ReadVector3(),
					Dir = s.ReadVector3(),
					Normal = s.ReadVector3(),
					Amount = s.ReadSingle()
				});
			}
		}
	}
	internal static class CloneGuns
	{
		private class Dropped
		{
			public MarrowEntityRecorder Rec;

			public GameObject Obj;

			public ushort Clone;

			public float Time;

			public bool Inner;

			public Transform Parent;

			public Vector3 LocalPos;

			public Quaternion LocalRot;

			public readonly List<MarrowBody> Created = new List<MarrowBody>();

			public readonly List<ValueTuple<Rigidbody, bool, bool>> Rbs = new List<ValueTuple<Rigidbody, bool, bool>>();

			public float FallSpeed;

			public float LastY;
		}

		private class Silenced
		{
			public ushort Clone;

			public Vector3 Pos;

			public float Time;

			public float From;
		}

		private class Loose
		{
			public GameObject Obj;

			public readonly List<Rigidbody> Rbs = new List<Rigidbody>();

			public float Until;

			public float FallSpeed;

			public float LastY;
		}

		private static readonly List<Dropped> _drops = new List<Dropped>();

		private static readonly HashSet<MarrowEntityRecorder> _dropped = new HashSet<MarrowEntityRecorder>();

		private static readonly HashSet<MarrowEntityRecorder> _suppressed = new HashSet<MarrowEntityRecorder>();

		private static readonly List<Silenced> _silenced = new List<Silenced>();

		private static readonly List<Loose> _loose = new List<Loose>();

		private static readonly HashSet<string> _seenSpawns = new HashSet<string>();

		private static Il2CppStructArray<RaycastHit> _hits;

		private static float _nextSweep;

		private static readonly List<CloneBody> _bodiesTmp = new List<CloneBody>();

		private static readonly Dictionary<int, bool> _isWeapon = new Dictionary<int, bool>();

		private const float LooseReach = 0.35f;

		internal static void Install(Harmony harmony)
		{
			global::System.Type typeFromHandle = typeof(CloneGuns);
			Prefix(AccessTools.Method(typeof(MarrowEntityRecorder), "Playback", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "SkipPlayback");
			MethodInfo val = AccessTools.Method(typeof(GunRecorder), "Playback", (global::System.Type[])null, (global::System.Type[])null);
			if (val != (MethodInfo)null && ((MemberInfo)val).DeclaringType == typeof(GunRecorder))
			{
				Prefix(val, typeFromHandle, "SkipPlayback");
			}
			Prefix(AccessTools.Method(typeof(ObjectRecorder), "CheckAndRunEvents", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "SkipEvents");
			Prefix(AccessTools.Method(typeof(MarrowEntityRecorder), "SetAllCaptureAnchors", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "SkipAnchor");
			Prefix(AccessTools.Method(typeof(SimpleSpawnRecorder), "OnInitializedPlayback", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "SkipSpawn");
			Prefix(AccessTools.Method(typeof(MarrowEntityRecorder), "OnInitializedPlayback", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "SkipEntitySpawn");
			Patches.Postfix("clones-spawn-physics", (MethodBase)(object)AccessTools.Method(typeof(SimpleSpawnRecorder), "AttemptModifyParticleSystem", (global::System.Type[])null, (global::System.Type[])null), typeFromHandle, "SpawnPhysics");
			Patches.BeforeGunFire((Func<Gun, bool>)SkipFire);
		}

		private static void Prefix(MethodInfo target, global::System.Type holder, string method)
		{
			if (target == (MethodInfo)null)
			{
				ClonesMod.Log.Warning("Clone guns: missing " + method);
				return;
			}
			global::System.Type declaringType = ((MemberInfo)target).DeclaringType;
			Patches.Prefix("clones-" + ((declaringType != null) ? ((MemberInfo)declaringType).Name : null) + "." + ((MemberInfo)target).Name, (MethodBase)(object)target, holder, method);
		}

		private static bool IsDropped(ObjectRecorder r)
		{
			MarrowEntityRecorder val = (MarrowEntityRecorder)(object)((r is MarrowEntityRecorder) ? r : null);
			if (val != null)
			{
				if (!_dropped.Contains(val))
				{
					return _suppressed.Contains(val);
				}
				return true;
			}
			return false;
		}

		private static bool SkipPlayback(MarrowEntityRecorder __instance)
		{
			return !IsDropped((ObjectRecorder)(object)__instance);
		}

		private static bool SkipEvents(ObjectRecorder __instance)
		{
			return !IsDropped(__instance);
		}

		private static bool SkipAnchor(MarrowEntityRecorder __instance, Transform transform)
		{
			if (!((Object)(object)transform == (Object)null))
			{
				return !IsDropped((ObjectRecorder)(object)__instance);
			}
			return true;
		}

		private static bool Near(Vector3 p, Transform t, float r)
		{
			//IL_0009: 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_0010: 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)
			if ((Object)(object)t != (Object)null)
			{
				Vector3 val = p - t.position;
				return ((Vector3)(ref val)).sqrMagnitude < r * r;
			}
			return false;
		}

		private static bool SkipFire(Gun __instance)
		{
			if (_dropped.Count == 0 || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			try
			{
				GunRecorder r = default(GunRecorder);
				if (GunRecorder.TryGetRecorderFromCache(__instance, ref r) && IsDropped((ObjectRecorder)(object)r))
				{
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		private static bool FromDeadClone(ObjectRecorder rec)
		{
			//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)
			WorldPlayer instance = WorldPlayer.Instance;
			if (rec == null || instance == null)
			{
				return false;
			}
			float playHead = WorldPlayer.playHead;
			ClonesMod.CollectBodies(_bodiesTmp);
			Enumerator<CloneBody> enumerator = _bodiesTmp.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (!current.GunsDown && !current.Dead && !RagdollTimeline.IsRagdolled(current.RecorderId))
					{
						continue;
					}
					float num = (current.GunsDown ? current.DownTime : playHead);
					if (!(rec.initTime < num - 0.05f))
					{
						if (rec.associatedRecorders != null && rec.associatedRecorders.Contains(current.RecorderId))
						{
							return true;
						}
						ObjectRecorder objectRecorder = instance.GetObjectRecorder(current.RecorderId);
						if (objectRecorder != null && objectRecorder.associatedRecorders != null && objectRecorder.associatedRecorders.Contains(rec.recorderID))
						{
							return true;
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return false;
		}

		private static bool SkipEntitySpawn(MarrowEntityRecorder __instance)
		{
			try
			{
				if (__instance is GunRecorder || !FromDeadClone((ObjectRecorder)(object)__instance))
				{
					return true;
				}
				_suppressed.Add(__instance);
				return false;
			}
			catch
			{
				return true;
			}
		}

		private static bool SkipSpawn(SimpleSpawnRecorder __instance)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ec: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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)
			if (__instance == null)
			{
				return true;
			}
			try
			{
				if (FromDeadClone((ObjectRecorder)(object)__instance))
				{
					return false;
				}
				string text = (((object)__instance.barcode)?.ToString() ?? "").ToLowerInvariant();
				if (text.Contains("blood") || text.Contains("gore") || text.Contains("wound") || text.Contains("decal") || text.Contains("splat") || text.Contains("impact") || text.Contains("flesh"))
				{
					return true;
				}
				float playHead = WorldPlayer.playHead;
				Vector3 position = __instance.position;
				ClonesMod.CollectBodies(_bodiesTmp);
				Enumerator<CloneBody> enumerator = _bodiesTmp.GetEnumerator();
				Vector3 val;
				try
				{
					while (enumerator.MoveNext())
					{
						CloneBody current = enumerator.Current;
						if (!current.GunsDown && !current.Dead && !RagdollTimeline.IsRagdolled(current.RecorderId))
						{
							continue;
						}
						if (!Near(position, current.HipsBone, 2f) && !Near(position, current.LeftHand, 1.2f) && !Near(position, current.RightHand, 1.2f))
						{
							if (!current.GunsDown)
							{
								continue;
							}
							val = position - current.DeathSpot;
							if (!(((Vector3)(ref val)).sqrMagnitude < 4f))
							{
								continue;
							}
						}
						return false;
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
				if (_silenced.Count == 0)
				{
					return true;
				}
				Enumerator<Silenced> enumerator2 = _silenced.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						Silenced current2 = enumerator2.Current;
						if (!(playHead < current2.From - 0.05f))
						{
							float num = Mathf.Min(1.5f + 2.5f * Mathf.Max(0f, playHead - current2.Time), 6f);
							val = position - current2.Pos;
							if (!(((Vector3)(ref val)).sqrMagnitude > num * num))
							{
								current2.Pos = position;
								current2.Time = playHead;
								return false;
							}
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
				}
			}
			catch
			{
			}
			return true;
		}

		private static bool IsCasingLike(string id)
		{
			id = id.ToLowerInvariant();
			if (!id.Contains("casing") && !id.Contains("shell") && !id.Contains("brass") && !id.Contains("cartridge"))
			{
				return id.Contains("mag");
			}
			return true;
		}

		private static void SpawnPhysics(SimpleSpawnRecorder __instance, GameObject root)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			try
			{
				string text = ((__instance == null) ? "" : ((object)__instance.barcode)?.ToString()) + " " + ((Object)root).name;
				bool flag = IsCasingLike(text);
				if (_seenSpawns.Add(text))
				{
					ClonesMod.Log.Msg("Timeline replayed spawn: " + text + " -> " + (flag ? "falls" : "left as is"));
				}
				if (!flag)
				{
					return;
				}
				Loose loose = new Loose
				{
					Obj = root,
					Until = Time.time + 10f,
					LastY = root.transform.position.y
				};
				MakePhysical(root, null, loose.Rbs);
				Transform transform = root.transform;
				Vector3 velocity = transform.right * Random.Range(1.2f, 2f) + transform.up * Random.Range(0.6f, 1.2f);
				Enumerator<Rigidbody> enumerator = loose.Rbs.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						Rigidbody current = enumerator.Current;
						current.velocity = velocity;
						current.angularVelocity = Random.insideUnitSphere * 8f;
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
				_loose.Add(loose);
			}
			catch
			{
			}
		}

		internal static void OnDeath(CloneBody body, global::System.Collections.Generic.IEnumerable<CloneBody> everyone)
		{
			//IL_003c: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			WorldPlayer instance = WorldPlayer.Instance;
			if (body == null || instance == null || instance.playbackRecorders == null)
			{
				return;
			}
			body.DeathSpot = (((Object)(object)body.HipsBone != (Object)null) ? body.HipsBone.position : ((Component)body.Avatar).transform.position);
			Transform[] hands = (Transform[])(object)new Transform[2] { body.LeftHand, body.RightHand };
			int num = 0;
			Enumerator<ObjectRecorder> enumerator = instance.playbackRecorders.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ObjectRecorder current = enumerator.Current;
					MarrowEntityRecorder val = (MarrowEntityRecorder)(object)((current is MarrowEntityRecorder) ? current : null);
					if (val != null && !(current is ATVRecorder) && !IsDropped((ObjectRecorder)(object)val))
					{
						GameObject playbackObject = val.playbackObject;
						if (!((Object)(object)playbackObject == (Object)null) && playbackObject.activeInHierarchy && !((Object)(object)HeldBy(playbackObject, hands, body, everyone) == (Object)null))
						{
							num += Drop(val, playbackObject, body);
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			ClonesMod.Log.Msg($"Clone {body.RecorderId} went down: dropped {num} item(s)");
		}

		internal static void Sweep(global::System.Collections.Generic.IEnumerable<CloneBody> everyone)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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)
			//IL_0117: 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)
			if (Time.unscaledTime < _nextSweep)
			{
				return;
			}
			_nextSweep = Time.unscaledTime + 0.25f;
			WorldPlayer instance = WorldPlayer.Instance;
			if (instance == null || instance.playbackRecorders == null)
			{
				return;
			}
			float playHead = WorldPlayer.playHead;
			global::System.Collections.Generic.IEnumerator<CloneBody> enumerator = everyone.GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (current == null || !current.GunsDown || playHead - current.DownTime > 3f || playHead < current.DownTime - 0.1f)
					{
						continue;
					}
					Enumerator<ObjectRecorder> enumerator2 = instance.playbackRecorders.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							ObjectRecorder current2 = enumerator2.Current;
							MarrowEntityRecorder val = (MarrowEntityRecorder)(object)((current2 is MarrowEntityRecorder) ? current2 : null);
							if (val == null || current2 is ATVRecorder || IsDropped((ObjectRecorder)(object)val))
							{
								continue;
							}
							GameObject playbackObject = val.playbackObject;
							if (!((Object)(object)playbackObject == (Object)null) && playbackObject.activeInHierarchy && !((Object)(object)playbackObject.transform.parent != (Object)null) && IsWeapon(playbackObject))
							{
								Vector3 val2 = playbackObject.transform.position - current.DeathSpot;
								if (!(((Vector3)(ref val2)).sqrMagnitude > 9f) && !NearLivingHand(playbackObject, everyone, 0.6f) && Drop(val, playbackObject, current) > 0)
								{
									ClonesMod.Log.Msg($"Clone {current.RecorderId}: dropped a loose {((Object)playbackObject).name} near its body");
								}
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
		}

		private static bool IsWeapon(GameObject obj)
		{
			int instanceID = ((Object)obj).GetInstanceID();
			bool result = default(bool);
			if (_isWeapon.TryGetValue(instanceID, ref result))
			{
				return result;
			}
			result = (Object)(object)obj.GetComponentInChildren<Gun>() != (Object)null || (Object)(object)obj.GetComponentInChildren<Magazine>() != (Object)null;
			if (_isWeapon.Count > 2048)
			{
				_isWeapon.Clear();
			}
			_isWeapon[instanceID] = result;
			return result;
		}

		private static int Drop(MarrowEntityRecorder rec, GameObject obj, CloneBody body)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = obj.transform;
			Dropped dropped = new Dropped
			{
				Rec = rec,
				Obj = obj,
				Clone = body.RecorderId,
				Time = WorldPlayer.playHead,
				Parent = transform.parent,
				LocalPos = transform.localPosition,
				LocalRot = transform.localRotation,
				LastY = transform.position.y
			};
			transform.SetParent((Transform)null, true);
			MakePhysical(obj, dropped.Created, null, dropped.Rbs);
			_drops.Add(dropped);
			_dropped.Add(rec);
			Gun componentInChildren = obj.GetComponentInChildren<Gun>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Transform val = (((Object)(object)componentInChildren.firePointTransform != (Object)null) ? componentInChildren.firePointTransform : transform);
				_silenced.Add(new Silenced
				{
					Clone = body.RecorderId,
					Pos = val.position,
					Time = dropped.Time,
					From = dropped.Time
				});
			}
			ClonesMod.Log.Msg($"  dropped {((Object)obj).name} ({dropped.Rbs.Count} body/bodies, {dropped.Created.Count} woken up)");
			int num = 1;
			WorldPlayer instance = WorldPlayer.Instance;
			if (instance == null || instance.playbackRecorders == null)
			{
				return num;
			}
			Enumerator<ObjectRecorder> enumerator = instance.playbackRecorders.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ObjectRecorder current = enumerator.Current;
					MarrowEntityRecorder val2 = (MarrowEntityRecorder)(object)((current is MarrowEntityRecorder) ? current : null);
					if (val2 != null && !IsDropped((ObjectRecorder)(object)val2))
					{
						GameObject playbackObject = val2.playbackObject;
						if (!((Object)(object)playbackObject == (Object)null) && !((Object)(object)playbackObject == (Object)(object)obj) && playbackObject.transform.IsChildOf(transform))
						{
							_drops.Add(new Dropped
							{
								Rec = val2,
								Obj = playbackObject,
								Clone = body.RecorderId,
								Time = dropped.Time,
								Inner = true,
								LastY = playbackObject.transform.position.y
							});
							_dropped.Add(val2);
							num++;
						}
					}
				}
				return num;
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static void MakePhysical(GameObject obj, List<MarrowBody> created, List<Rigidbody> rbsOut, List<ValueTuple<Rigidbody, bool, bool>> states = null)
		{
			//IL_00cc: 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)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			HashSet<int> val = new HashSet<int>();
			MarrowEntity val2 = obj.GetComponentInChildren<MarrowEntity>() ?? obj.GetComponentInParent<MarrowEntity>();
			if ((Object)(object)val2 != (Object)null)
			{
				Il2CppReferenceArray<MarrowBody> val3 = null;
				try
				{
					val3 = val2.Bodies;
				}
				catch
				{
				}
				if (val3 != null)
				{
					global::System.Collections.Generic.IEnumerator<MarrowBody> enumerator = ((Il2CppArrayBase<MarrowBody>)(object)val3).GetEnumerator();
					try
					{
						while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
						{
							MarrowBody current = enumerator.Current;
							if ((Object)(object)current == (Object)null)
							{
								continue;
							}
							try
							{
								if (!current.HasRigidbody)
								{
									current.CreateRigidbody();
									created?.Add(current);
								}
							}
							catch
							{
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator)?.Dispose();
					}
				}
			}
			global::System.Collections.Generic.IEnumerator<Rigidbody> enumerator2 = obj.GetComponentsInChildren<Rigidbody>().GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator2).MoveNext())
				{
					Rigidbody current2 = enumerator2.Current;
					if (!((Object)(object)current2 == (Object)null) && val.Add(((Object)current2).GetInstanceID()))
					{
						states?.Add(new ValueTuple<Rigidbody, bool, bool>(current2, current2.isKinematic, current2.useGravity));
						rbsOut?.Add(current2);
						current2.isKinematic = false;
						current2.useGravity = true;
						current2.constraints = (RigidbodyConstraints)0;
						current2.detectCollisions = true;
						current2.velocity = Vector3.zero;
						current2.angularVelocity = Random.insideUnitSphere * 1.5f;
						current2.WakeUp();
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2)?.Dispose();
			}
		}

		internal static void Maintain()
		{
			if (_drops.Count == 0 && _suppressed.Count == 0 && _silenced.Count == 0)
			{
				return;
			}
			float now = WorldPlayer.playHead;
			for (int num = _drops.Count - 1; num >= 0; num--)
			{
				Dropped dropped = _drops[num];
				if (dropped.Rec == null || (Object)(object)dropped.Obj == (Object)null || (Object)(object)dropped.Rec.playbackObject != (Object)(object)dropped.Obj || now < dropped.Time - 0.05f)
				{
					Undrop(dropped);
					_drops.RemoveAt(num);
				}
				else if (!dropped.Inner && (Object)(object)dropped.Obj.transform.parent != (Object)null)
				{
					dropped.Obj.transform.SetParent((Transform)null, true);
				}
			}
			_suppressed.RemoveWhere((Predicate<MarrowEntityRecorder>)((MarrowEntityRecorder r) => r == null || now < ((ObjectRecorder)r).initTime - 0.02f));
			if (now < 0.05f)
			{
				_silenced.Clear();
				return;
			}
			_silenced.RemoveAll((Predicate<Silenced>)((Silenced s) => now < s.From - 0.05f));
		}

		internal static void FixedTick(float dt)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0041: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<Dropped> enumerator = _drops.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Dropped current = enumerator.Current;
					if (current.Inner || (Object)(object)current.Obj == (Object)null)
					{
						continue;
					}
					Enumerator<ValueTuple<Rigidbody, bool, bool>> enumerator2 = current.Rbs.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							Rigidbody item = enumerator2.Current.Item1;
							if ((Object)(object)item != (Object)null && item.isKinematic)
							{
								item.isKinematic = false;
								item.useGravity = true;
								item.WakeUp();
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
					Settle(current.Obj, current.Rbs, ref current.FallSpeed, ref current.LastY, dt);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			for (int num = _loose.Count - 1; num >= 0; num--)
			{
				Loose loose = _loose[num];
				if ((Object)(object)loose.Obj == (Object)null || Time.time > loose.Until)
				{
					_loose.RemoveAt(num);
				}
				else
				{
					Settle(loose.Obj, loose.Rbs, ref loose.FallSpeed, ref loose.LastY, dt);
				}
			}
		}

		private static void Settle(GameObject obj, List<ValueTuple<Rigidbody, bool, bool>> rbs, ref float speed, ref float lastY, float dt)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			List<Rigidbody> val = new List<Rigidbody>(rbs.Count);
			Enumerator<ValueTuple<Rigidbody, bool, bool>> enumerator = rbs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Rigidbody item = enumerator.Current.Item1;
					if ((Object)(object)item != (Object)null)
					{
						val.Add(item);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Settle(obj, val, ref speed, ref lastY, dt);
		}

		private static void Settle(GameObject obj, List<Rigidbody> rbs, ref float speed, ref float lastY, float dt)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0157: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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)
			Rigidbody val = null;
			Enumerator<Rigidbody> enumerator = rbs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Rigidbody current = enumerator.Current;
					if ((Object)(object)current != (Object)null)
					{
						val = current;
						break;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			float num = (((Object)(object)val != (Object)null) ? val.position.y : obj.transform.position.y);
			bool num2 = lastY - num > 0.002f;
			lastY = num;
			if (num2)
			{
				speed = 0f;
				return;
			}
			float num3 = GapBelow(obj);
			if (num3 <= 0.01f)
			{
				speed = 0f;
			}
			else
			{
				if ((Object)(object)val != (Object)null && !val.isKinematic && val.velocity.y < -0.05f)
				{
					return;
				}
				speed = Mathf.Min(speed + 9.81f * dt, 20f);
				Vector3 val2 = Vector3.down * Mathf.Min(speed * dt, num3);
				if ((Object)(object)val != (Object)null)
				{
					enumerator = rbs.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							Rigidbody current2 = enumerator.Current;
							if (!((Object)(object)current2 == (Object)null))
							{
								if (current2.isKinematic)
								{
									current2.MovePosition(current2.position + val2);
								}
								else
								{
									current2.position += val2;
								}
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
					}
					lastY = val.position.y;
				}
				else
				{
					Transform transform = obj.transform;
					transform.position += val2;
					lastY = obj.transform.position.y;
				}
			}
		}

		private static float GapBelow(GameObject obj)
		{
			//IL_0044: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_010b: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			Transform transform = obj.transform;
			float num = 3.4028235E+38f;
			global::System.Collections.Generic.IEnumerator<Collider> enumerator = obj.GetComponentsInChildren<Collider>().GetEnumerator();
			Bounds bounds;
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					Collider current = enumerator.Current;
					if ((Object)(object)current != (Object)null && current.enabled && !current.isTrigger)
					{
						float num2 = num;
						bounds = current.bounds;
						num = Mathf.Min(num2, ((Bounds)(ref bounds)).min.y);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
			if (num == 3.4028235E+38f)
			{
				global::System.Collections.Generic.IEnumerator<Renderer> enumerator2 = obj.GetComponentsInChildren<Renderer>().GetEnumerator();
				try
				{
					while (((global::System.Collections.IEnumerator)enumerator2).MoveNext())
					{
						Renderer current2 = enumerator2.Current;
						if ((Object)(object)current2 != (Object)null && current2.enabled)
						{
							float num3 = num;
							bounds = current2.bounds;
							num = Mathf.Min(num3, ((Bounds)(ref bounds)).min.y);
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator2)?.Dispose();
				}
			}
			if (num == 3.4028235E+38f)
			{
				num = transform.position.y;
			}
			Vector3 val = new Vector3(transform.position.x, num + 0.05f, transform.position.z);
			if (_hits == null)
			{
				_hits = new Il2CppStructArray<RaycastHit>(16L);
			}
			int num4 = Physics.RaycastNonAlloc(val, Vector3.down, _hits, 60f, -5, (QueryTriggerInteraction)1);
			float num5 = 60f;
			for (int i = 0; i < num4; i++)
			{
				RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i];
				if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(transform))
				{
					Rigidbody attachedRigidbody = ((RaycastHit)(ref val2)).collider.attachedRigidbody;
					if (!((Object)(object)attachedRigidbody != (Object)null) || !((Component)attachedRigidbody).transform.IsChildOf(transform))
					{
						num5 = Mathf.Min(num5, ((RaycastHit)(ref val2)).distance);
					}
				}
			}
			if (!(num5 >= 60f))
			{
				return Mathf.Max(0f, num5 - 0.05f);
			}
			return 0f;
		}

		private static void Undrop(Dropped d)
		{
			//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_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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_0066: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (d.Rec != null)
			{
				_dropped.Remove(d.Rec);
			}
			if ((Object)(object)d.Obj == (Object)null)
			{
				return;
			}
			Enumerator<ValueTuple<Rigidbody, bool, bool>> enumerator = d.Rbs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ValueTuple<Rigidbody, bool, bool> current = enumerator.Current;
					Rigidbody item = current.Item1;
					bool item2 = current.Item2;
					bool item3 = current.Item3;
					if (!((Object)(object)item == (Object)null))
					{
						item.velocity = Vector3.zero;
						item.angularVelocity = Vector3.zero;
						item.isKinematic = item2;
						item.useGravity = item3;
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<MarrowBody> enumerator2 = d.Created.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					MarrowBody current2 = enumerator2.Current;
					try
					{
						if ((Object)(object)current2 != (Object)null && current2.HasRigidbody)
						{
							current2.DestroyRigidbody();
						}
					}
					catch
					{
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			if ((Object)(object)d.Parent != (Object)null && !d.Inner)
			{
				d.Obj.transform.SetParent(d.Parent, false);
				d.Obj.transform.localPosition = d.LocalPos;
				d.Obj.transform.localRotation = d.LocalRot;
			}
		}

		internal static void OnRevive(CloneBody body)
		{
			if (body == null)
			{
				return;
			}
			for (int num = _drops.Count - 1; num >= 0; num--)
			{
				if (_drops[num].Clone == body.RecorderId)
				{
					Undrop(_drops[num]);
					_drops.RemoveAt(num);
				}
			}
			_silenced.RemoveAll((Predicate<Silenced>)((Silenced s) => s.Clone == body.RecorderId));
		}

		internal static void Clear()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<Dropped> enumerator = _drops.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Undrop(enumerator.Current);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			_drops.Clear();
			_dropped.Clear();
			_suppressed.Clear();
			_silenced.Clear();
			_loose.Clear();
		}

		private static Transform HeldBy(GameObject obj, Transform[] hands, CloneBody body, global::System.Collections.Generic.IEnumerable<CloneBody> everyone)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = obj.transform;
			Transform[] array = hands;
			foreach (Transform val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)transform.parent != (Object)null && transform.IsChildOf(val))
				{
					return val;
				}
			}
			if ((Object)(object)transform.parent != (Object)null)
			{
				return null;
			}
			Transform val2 = null;
			float num = 0.35f;
			array = hands;
			foreach (Transform val3 in array)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					float num2 = DistanceTo(obj, val3.position);
					if (num2 < num)
					{
						num = num2;
						val2 = val3;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			global::System.Collections.Generic.IEnumerator<CloneBody> enumerator = everyone.GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (current == null || current == body || current.GunsDown)
					{
						continue;
					}
					array = (Transform[])(object)new Transform[2] { current.LeftHand, current.RightHand };
					foreach (Transform val4 in array)
					{
						if ((Object)(object)val4 != (Object)null && DistanceTo(obj, val4.position) < num)
						{
							return null;
						}
					}
				}
				return val2;
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
		}

		private static bool NearLivingHand(GameObject obj, global::System.Collections.Generic.IEnumerable<CloneBody> everyone, float reach)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			global::System.Collections.Generic.IEnumerator<CloneBody> enumerator = everyone.GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					CloneBody current = enumerator.Current;
					if (current != null && !current.GunsDown)
					{
						if ((Object)(object)current.LeftHand != (Object)null && DistanceTo(obj, current.LeftHand.position) < reach)
						{
							return true;
						}
						if ((Object)(object)current.RightHand != (Object)null && DistanceTo(obj, current.RightHand.position) < reach)
						{
							return true;
						}
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
			return false;
		}

		private static float DistanceTo(GameObject obj, Vector3 p)
		{
			//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_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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Distance(obj.transform.position, p);
			global::System.Collections.Generic.IEnumerator<Collider> enumerator = obj.GetComponentsInChildren<Collider>().GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					Collider current = enumerator.Current;
					if (!((Object)(object)current == (Object)null) && current.enabled && !current.isTrigger)
					{
						float num2 = num;
						Bounds bounds = current.bounds;
						num = Mathf.Min(num2, Vector3.Distance(((Bounds)(ref bounds)).ClosestPoint(p), p));
					}
				}
				return num;
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
		}
	}
	internal static class TimelineAccess
	{
		internal static void CollectPlaybackObjects(List<GameObject> into)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			into.Clear();
			WorldPlayer instance = WorldPlayer.Instance;
			if (instance == null || instance.playbackRecorders == null)
			{
				return;
			}
			Enumerator<ObjectRecorder> enumerator = instance.playbackRecorders.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ObjectRecorder current = enumerator.Current;
					MarrowEntityRecorder val = (MarrowEntityRecorder)(object)((current is MarrowEntityRecorder) ? current : null);
					if (val != null && (Object)(object)val.playbackObject != (Object)null)
					{
						into.Add(val.playbackObject);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal static void CollectCloneAvatars(List<Avatar> into, List<ushort> ids)
		{
			//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)
			into.Clear();
			ids.Clear();
			WorldPlayer instance = WorldPlayer.Instance;
			if (instance == null || instance.playbackRecorders == null)
			{
				return;
			}
			Enumerator<ObjectRecorder> enumerator = instance.playbackRecorders.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ObjectRecorder current = enumerator.Current;
					RigmanagerRecorder val = (RigmanagerRecorder)(object)((current is RigmanagerRecorder) ? current : null);
					if (val != null && (Object)(object)val.currentPlaybackAvatar != (Object)null && ((Component)val.currentPlaybackAvatar).gameObject.activeInHierarchy)
					{
						into.Add(val.currentPlaybackAvatar);
						ids.Add(((ObjectRecorder)val).recorderID);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}
	}
}
namespace Sling
{
	internal static class SlingTimeline
	{
		internal const byte RecorderId = 230;

		private static bool _wasRecording;

		private static SlingStrapRecorder _current;

		internal static void Register()
		{
			FieldInfo field = typeof(SerializableRegistry).GetField("recorderTypeRegistry", (BindingFlags)40);
			if (((field != null) ? field.GetValue((object)null) : null) is Dictionary<byte, global::System.Type> val)
			{
				val[(byte)230] = typeof(SlingStrapRecorder);
			}
		}

		internal static void Tick(bool slingActive)
		{
			if (!WorldPlayer.recording)
			{
				_current = null;
				_wasRecording = false;
				return;
			}
			if (!_wasRecording)
			{
				_current = null;
			}
			_wasRecording = true;
			if (_current == null && slingActive)
			{
				WorldPlayer val = ((TimelineMainClass.timelineHolder != null) ? TimelineMainClass.timelineHolder.worldPlayer : WorldPlayer.Instance);
				if (val != null)
				{
					Register();
					SlingStrapRecorder slingStrapRecorder = new SlingStrapRecorder();
					((ObjectRecorder)slingStrapRecorder).OnInitializedRecording((Object)null);
					((ObjectRecorder)slingStrapRecorder).recording = true;
					((ObjectRecorder)slingStrapRecorder).initTime = WorldPlayer.playHead;
					val.AddRecorderToRecord((ObjectRecorder)(object)slingStrapRecorder);
					_current = slingStrapRecorder;
				}
			}
		}
	}
	public class SlingStrapRecorder : ObjectRecorder
	{
		private readonly PolyTrack _track = new PolyTrack();

		private readonly Vector3[] _buf = (Vector3[])(object)new Vector3[24];

		private float _lastCapture = -3.4028235E+38f;

		private StrapRenderer _strap;

		private byte _style;

		private float _widthCm = 3.5f;

		public override byte SerializeableID => 230;

		public override string GetName()
		{
			return "Gun Sling";
		}

		public override void OnInitializedRecording(Object obj)
		{
			_track.Clear();
		}

		public override void Capture(float time)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!(time - _lastCapture < 1f / 30f))
			{
				_lastCapture = time;
				int num = SlingMod.StrapSnapshot(_buf);
				if (num >= 2)
				{
					_style = (byte)SlingMod.CurrentStyle;
					_widthCm = SlingMod.WidthCm.Value;
				}
				_track.Add(time, _buf, (num >= 2) ? num : 0);
			}
		}

		public override void OnRecordingCompleted()
		{
		}

		public override void OnInitializedPlayback()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			if (_strap == null)
			{
				_strap = new StrapRenderer();
				_strap.Create("Timeline_SlingStrap");
			}
		}

		public override void Playback(float time)
		{
			if (_strap == null)
			{
				((ObjectRecorder)this).OnInitializedPlayback();
			}
			int num = _track.Sample(time, _buf);
			if (num < 2)
			{
				_strap.Hide();
			}
			else
			{
				_strap.Draw(_buf, num, (SlingStyle)_style, _widthCm / 100f);
			}
		}

		public override void OnPlaybackCompleted()
		{
			StrapRenderer strap = _strap;
			if (strap != null)
			{
				strap.Hide();
			}
		}

		public override void OnHide(bool hide)
		{
			if (hide)
			{
				StrapRenderer strap = _strap;
				if (strap != null)
				{
					strap.Hide();
				}
			}
		}

		public override int GetSize()
		{
			return ((ObjectRecorder)this).GetSize() + 1 + 4 + _track.ByteSize;
		}

		public override void WriteToStream(BinaryStream stream)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).WriteToStream(stream);
			stream.WriteByte(_style);
			stream.WriteSingle(_widthCm);
			stream.WriteInt32(_track.FrameCount);
			for (int i = 0; i < _track.FrameCount; i++)
			{
				stream.WriteSingle(_track.Times[i]);
				byte b = _track.Counts[i];
				stream.WriteByte(b);
				int num = _track.Starts[i];
				for (int j = 0; j < b; j++)
				{
					stream.WriteVector3(_track.Points[num + j]);
				}
			}
		}

		public override void ReadFromStream(BinaryStream stream)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).ReadFromStream(stream);
			_style = stream.ReadByte();
			_widthCm = stream.ReadSingle();
			_track.Clear();
			int num = stream.ReadInt32();
			Vector3[] array = (Vector3[])(object)new Vector3[255];
			for (int i = 0; i < num; i++)
			{
				float num2 = stream.ReadSingle();
				byte b = stream.ReadByte();
				for (int j = 0; j < b; j++)
				{
					array[j] = stream.ReadVector3();
				}
				_track.Add(num2, array, (int)b);
			}
		}
	}
}
namespace Heli
{
	internal static class HeliTimeline
	{
		internal const byte RecorderId = 236;

		internal static readonly Dictionary<int, HeliRecorder> Drivers = new Dictionary<int, HeliRecorder>();

		private static bool _wasRecording;

		private static HeliRecorder _current;

		internal static void Register()
		{
			FieldInfo field = typeof(SerializableRegistry).GetField("recorderTypeRegistry", (BindingFlags)40);
			if (((field != null) ? field.GetValue((object)null) : null) is Dictionary<byte, global::System.Type> val)
			{
				val[(byte)236] = typeof(HeliRecorder);
			}
		}

		internal static void Tick(bool anyHeli)
		{
			if (!WorldPlayer.recording)
			{
				_current = null;
				_wasRecording = false;
				return;
			}
			if (!_wasRecording)
			{
				_current = null;
			}
			_wasRecording = true;
			if (_current == null && anyHeli)
			{
				WorldPlayer val = ((TimelineMainClass.timelineHolder != null) ? TimelineMainClass.timelineHolder.worldPlayer : WorldPlayer.Instance);
				if (val != null)
				{
					Register();
					HeliRecorder heliRecorder = new HeliRecorder();
					((ObjectRecorder)heliRecorder).OnInitializedRecording((Object)null);
					((ObjectRecorder)heliRecorder).recording = true;
					((ObjectRecorder)heliRecorder).initTime = WorldPlayer.playHead;
					val.AddRecorderToRecord((ObjectRecorder)(object)heliRecorder);
					_current = heliRecorder;
				}
			}
		}

		internal static void OnExplode(Vector3 at)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (_current != null && WorldPlayer.recording)
			{
				_current.AddBoom(WorldPlayer.playHead, at);
			}
		}
	}
	public class HeliRecorder : ObjectRecorder
	{
		private struct Frame
		{
			public float Time;

			public float Rpm;

			public Vector3 Pos;

			public Quaternion Rot;

			public byte Flags;

			public sbyte Cx;

			public sbyte Cy;
		}

		private readonly Dictionary<int, List<Frame>> _tracks = new Dictionary<int, List<Frame>>();

		private readonly List<ValueTuple<float, Vector3>> _booms = new List<ValueTuple<float, Vector3>>();

		private readonly Dictionary<int, Heli> _ghosts = new Dictionary<int, Heli>();

		private readonly HashSet<int> _driving = new HashSet<int>();

		private float _lastCapture = -3.4028235E+38f;

		private float _lastPlayback = -3.4028235E+38f;

		private bool _hidden;

		public override byte SerializeableID => 236;

		public override string GetName()
		{
			return "Helicopter";
		}

		public override void OnInitializedRecording(Object obj)
		{
			_tracks.Clear();
			_booms.Clear();
		}

		public override void Capture(float time)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (time - _lastCapture < 1f / 15f)
			{
				return;
			}
			_lastCapture = time;
			Enumerator<int, Heli> enumerator = HeliMod.Helis.Values.GetEnumerator();
			try
			{
				List<Frame> val = default(List<Frame>);
				while (enumerator.MoveNext())
				{
					Heli current = enumerator.Current;
					if (!((Object)(object)current.Root == (Object)null) && !current.Driven)
					{
						if (!_tracks.TryGetValue(current.Key, ref val))
						{
							val = (_tracks[current.Key] = new List<Frame>());
						}
						val.Add(new Frame
						{
							Time = time,
							Pos = current.Pos,
							Rot = current.Rot,
							Rpm = current.Rpm,
							Flags = (byte)((current.RopesDown ? 4 : 0) | (current.Crashing ? 8 : 0)),
							Cx = (sbyte)Mathf.RoundToInt(current.Cyclic.x * 100f),
							Cy = (sbyte)Mathf.RoundToInt(current.Cyclic.y * 100f)
						});
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal void AddBoom(float time, Vector3 at)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_booms.Add(new ValueTuple<float, Vector3>(time, at));
		}

		public override void OnRecordingCompleted()
		{
		}

		public override void OnInitializedPlayback()
		{
			_lastPlayback = -3.4028235E+38f;
		}

		public override void Playback(float time)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: 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_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			if (time < _lastPlayback)
			{
				_lastPlayback = -3.4028235E+38f;
			}
			if (_lastPlayback != -3.4028235E+38f && time - _lastPlayback < 1f)
			{
				Enumerator<ValueTuple<float, Vector3>> enumerator = _booms.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						ValueTuple<float, Vector3> current = enumerator.Current;
						float item = current.Item1;
						Vector3 item2 = current.Item2;
						if (item > _lastPlayback && item <= time)
						{
							Explosions.Spawn(true, item2);
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			_lastPlayback = time;
			Enumerator<int, List<Frame>> enumerator2 = _tracks.GetEnumerator();
			try
			{
				Heli val = default(Heli);
				while (enumerator2.MoveNext())
				{
					KeyValuePair<int, List<Frame>> current2 = enumerator2.Current;
					_ghosts.TryGetValue(current2.Key, ref val);
					Frame f2;
					if (!_hidden && Drive(current2.Key, out var live))
					{
						if (val != null)
						{
							HeliMod.Replays.Remove(val);
							val.Destroy();
							_ghosts.Remove(current2.Key);
						}
						if (!Sample(current2.Value, time, out var f))
						{
							f = ((time <= current2.Value[0].Time) ? current2.Value[0] : current2.Value[current2.Value.Count - 1]);
						}
						live.ReplayPos = f.Pos;
						live.ReplayRot = f.Rot;
						live.Rpm = f.Rpm;
						live.RopesDown = (f.Flags & 4) != 0;
						live.Cyclic = new Vector2((float)f.Cx / 100f, (float)f.Cy / 100f);
					}
					else if (_hidden || !Sample(current2.Value, time, out f2))
					{
						if (val != null)
						{
							HeliMod.Replays.Remove(val);
							val.Destroy();
							_ghosts.Remove(current2.Key);
						}
					}
					else
					{
						if (val == null || (Object)(object)val.Root == (Object)null)
						{
							val = Heli.Create((Kind)2, (byte)255, (byte)(current2.Key & 0xFF), f2.Pos, ((Quaternion)(ref f2.Rot)).eulerAngles.y);
							val.Pos = (val.PrevPos = f2.Pos);
							val.Rot = (val.PrevRot = f2.Rot);
							_ghosts[current2.Key] = val;
							HeliMod.Replays.Add(val);
						}
						val.ReplayPos = f2.Pos;
						val.ReplayRot = f2.Rot;
						val.Rpm = f2.Rpm;
						val.RopesDown = (f2.Flags & 4) != 0;
						val.Cyclic = new Vector2((float)f2.Cx / 100f, (float)f2.Cy / 100f);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private bool Drive(int key, out Heli live)
		{
			live = null;
			List<Frame> val = default(List<Frame>);
			if (_tracks.TryGetValue(key, ref val) && val.Count == 0)
			{
				return false;
			}
			Heli val2 = default(Heli);
			HeliRecorder heliRecorder = default(HeliRecorder);
			if (!HeliMod.Helis.TryGetValue(key, ref val2) || val2 == null || (Object)(object)val2.Root == (Object)null || val2.Crashing || (HeliMod.Online && val2.Owner != HeliMod.LocalId) || val2 == HeliMod.Piloting || (HeliTimeline.Drivers.TryGetValue(key, ref heliRecorder) && heliRecorder != this))
			{
				Release(key);
				return false;
			}
			HeliTimeline.Drivers[key] = this;
			_driving.Add(key);
			val2.Driven = true;
			live = val2;
			return true;
		}

		private void Release(int key)
		{
			if (_driving.Remove(key))
			{
				HeliRecorder heliRecorder = default(HeliRecorder);
				if (HeliTimeline.Drivers.TryGetValue(key, ref heliRecorder) && heliRecorder == this)
				{
					HeliTimeline.Drivers.Remove(key);
				}
				Heli val = default(Heli);
				if (HeliMod.Helis.TryGetValue(key, ref val) && val != null)
				{
					val.Driven = false;
				}
			}
		}

		private static bool Sample(List<Frame> list, float time, out Frame f)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			f = default(Frame);
			if (list.Count == 0 || time < list[0].Time || time > list[list.Count - 1].Time + 0.2f)
			{
				return false;
			}
			int num = 0;
			int num2 = list.Count - 1;
			while (num < num2)
			{
				int num3 = (num + num2 + 1) / 2;
				if (list[num3].Time <= time)
				{
					num = num3;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			int num4 = Mathf.Min(num + 1, list.Count - 1);
			if (list[num4].Time - list[num].Time > 0.6f)
			{
				return false;
			}
			float num5 = ((num4 == num) ? 0f : Mathf.InverseLerp(list[num].Time, list[num4].Time, time));
			f = list[num];
			f.Pos = Vector3.Lerp(list[num].Pos, list[num4].Pos, num5);
			f.Rot = Quaternion.Slerp(list[num].Rot, list[num4].Rot, num5);
			f.Rpm = Mathf.Lerp(list[num].Rpm, list[num4].Rpm, num5);
			return true;
		}

		public override void OnPlaybackCompleted()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<int> enumerator = new List<int>((global::System.Collections.Generic.IEnumerable<int>)_driving).GetEnumerator();
			try
			{
				Heli val = default(Heli);
				while (enumerator.MoveNext())
				{
					int current = enumerator.Current;
					HeliMod.Helis.TryGetValue(current, ref val);
					Release(current);
					if (val != null && (Object)(object)val.Root != (Object)null)
					{
						HeliMod.DespawnAfterReplay(val);
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			RemoveGhosts();
		}

		public override void OnHide(bool hide)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			_hidden = hide;
			if (!hide)
			{
				return;
			}
			Enumerator<int> enumerator = new List<int>((global::System.Collections.Generic.IEnumerable<int>)_driving).GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					int current = enumerator.Current;
					Release(current);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			RemoveGhosts();
		}

		private void RemoveGhosts()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<int, Heli> enumerator = _ghosts.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Heli current = enumerator.Current;
					HeliMod.Replays.Remove(current);
					current.Destroy();
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			_ghosts.Clear();
		}

		public override int GetSize()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			int num = ((ObjectRecorder)this).GetSize() + 4 + 4 + _booms.Count * 16;
			Enumerator<int, List<Frame>> enumerator = _tracks.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					List<Frame> current = enumerator.Current;
					num += 8 + current.Count * 39;
				}
				return num;
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void WriteToStream(BinaryStream s)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).WriteToStream(s);
			s.WriteInt32(_tracks.Count);
			Enumerator<int, List<Frame>> enumerator = _tracks.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<int, List<Frame>> current = enumerator.Current;
					s.WriteInt32(current.Key);
					s.WriteInt32(current.Value.Count);
					Enumerator<Frame> enumerator2 = current.Value.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							Frame current2 = enumerator2.Current;
							s.WriteSingle(current2.Time);
							s.WriteVector3(current2.Pos);
							s.WriteQuaternion(current2.Rot);
							s.WriteSingle(current2.Rpm);
							s.WriteByte(current2.Flags);
							s.WriteByte((byte)current2.Cx);
							s.WriteByte((byte)current2.Cy);
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			s.WriteInt32(_booms.Count);
			Enumerator<ValueTuple<float, Vector3>> enumerator3 = _booms.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					ValueTuple<float, Vector3> current3 = enumerator3.Current;
					float item = current3.Item1;
					Vector3 item2 = current3.Item2;
					s.WriteSingle(item);
					s.WriteVector3(item2);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public override void ReadFromStream(BinaryStream s)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			((ObjectRecorder)this).ReadFromStream(s);
			_tracks.Clear();
			_booms.Clear();
			int num = s.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				int num2 = s.ReadInt32();
				int num3 = s.ReadInt32();
				List<Frame> val = new List<Frame>(num3);
				for (int j = 0; j < num3; j++)
				{
					val.Add(new Frame
					{
						Time = s.ReadSingle(),
						Pos = s.ReadVector3(),
						Rot = s.ReadQuaternion(),
						Rpm = s.ReadSingle(),
						Flags = s.ReadByte(),
						Cx = (sbyte)s.ReadByte(),
						Cy = (sbyte)s.ReadByte()
					});
				}
				_tracks[num2] = val;
			}
			int num4 = s.ReadInt32();
			for (int k = 0; k < num4; k++)
			{
				_booms.Add(new ValueTuple<float, Vector3>(s.ReadSingle(), s.ReadVector3()));
			}
		}
	}
}
namespace GunJam
{
	internal static class JamTimeline
	{
		internal const byte RecorderId = 233;

		private static bool _wasRecording;

		private static GunJamRecorder _current;

		internal static v