Decompiled source of crimson v1.1.0

Mods/Crimson.dll

Decompiled a day ago
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BoneLib;
using BoneLib.BoneMenu;
using Crimson;
using Crimson.Core;
using HarmonyLib;
using Il2CppCysharp.Threading.Tasks;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Data;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Audio;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.VFX;
using Il2CppSLZ.VRMK;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(CrimsonMod), "Crimson", "1.1.8", "Crimson Mod Project", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: InternalsVisibleTo("CrimsonFusion")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Crimson")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.8.0")]
[assembly: AssemblyInformationalVersion("1.1.8")]
[assembly: AssemblyProduct("Crimson")]
[assembly: AssemblyTitle("Crimson")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.8.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Crimson
{
	public sealed class AudioEffects
	{
		private readonly AudioClip[] _drips = (AudioClip[])(object)new AudioClip[31];

		private readonly AudioClip[] _cracks = (AudioClip[])(object)new AudioClip[8];

		private readonly ShuffleBag _dripBag = new ShuffleBag(31, 7021);

		private readonly ShuffleBag _crackBag = new ShuffleBag(8, 1029);

		private readonly AudioSource[] _voices = (AudioSource[])(object)new AudioSource[12];

		private GameObject? _root;

		private AudioClip? _ringClip;

		private AudioSource? _ring;

		private Audio3dManager? _manager;

		private float _trauma;

		private float _nextDrip;

		private float _lastBlast = -10f;

		private Vector3 _lastBlastPosition;

		private float _baselineCutoff = 22000f;

		private bool _writingCutoff;

		private bool _hasMuffled;

		internal int BlastCount { get; private set; }

		internal void Ensure()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//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)
			if (!Object.op_Implicit((Object)(object)_root))
			{
				_root = new GameObject("Crimson audio");
				Object.DontDestroyOnLoad((Object)(object)_root);
				for (int i = 0; i < 31; i++)
				{
					_drips[i] = Clip($"Crimson drip {i + 1:00}", SoundBank.Drip(i));
				}
				for (int j = 0; j < 8; j++)
				{
					_cracks[j] = Clip($"Crimson crack {j + 1:00}", SoundBank.Crack(j));
				}
				_ringClip = Clip("Crimson ringing", SoundBank.Ring());
				for (int k = 0; k < _voices.Length; k++)
				{
					GameObject val = new GameObject($"Crimson voice {k}");
					val.transform.SetParent(_root.transform, false);
					AudioSource val2 = val.AddComponent<AudioSource>();
					val2.playOnAwake = false;
					val2.spatialBlend = 1f;
					val2.dopplerLevel = 0f;
					val2.rolloffMode = (AudioRolloffMode)0;
					val2.minDistance = 0.6f;
					val2.maxDistance = 12f;
					_voices[k] = val2;
				}
				_ring = _root.AddComponent<AudioSource>();
				_ring.playOnAwake = false;
				_ring.spatialBlend = 0f;
				_ring.loop = true;
				_ring.clip = _ringClip;
				_ring.volume = 0f;
				_ring.priority = 100;
			}
		}

		private static AudioClip Clip(string name, float[] samples)
		{
			AudioClip obj = AudioClip.Create(name, samples.Length, 1, 24000, false);
			obj.SetData(Il2CppStructArray<float>.op_Implicit(samples), 0);
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		private void Play(AudioClip clip, Vector3 point, float volume)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			AudioSource[] voices = _voices;
			foreach (AudioSource val in voices)
			{
				if (Object.op_Implicit((Object)(object)val) && !val.isPlaying)
				{
					((Component)val).transform.position = point;
					val.clip = clip;
					val.volume = volume;
					val.pitch = Random.Range(0.87f, 1.13f);
					val.outputAudioMixerGroup = Audio.SoftInteraction;
					val.Play();
					break;
				}
			}
		}

		internal void Drip(Vector3 point)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Sounds.Value && !(Time.unscaledTime < _nextDrip))
			{
				Ensure();
				_nextDrip = Time.unscaledTime + Random.Range(0.065f, 0.18f);
				Play(_drips[_dripBag.Next()], point, Settings.SoundVolume.Value * Random.Range(0.45f, 0.9f));
			}
		}

		internal void Crack(Vector3 point)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Sounds.Value)
			{
				Ensure();
				Play(_cracks[_crackBag.Next()], point, Settings.SoundVolume.Value * Random.Range(0.7f, 1f));
			}
		}

		internal void Explosion(Vector3 point, float radius)
		{
			//IL_005e: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.Enabled.Value || !Settings.Tinnitus.Value || !Object.op_Implicit((Object)(object)Player.Head))
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime - _lastBlast < 0.15f)
			{
				Vector3 val = point - _lastBlastPosition;
				if (((Vector3)(ref val)).sqrMagnitude < 1f)
				{
					return;
				}
			}
			_lastBlast = unscaledTime;
			_lastBlastPosition = point;
			float num = Mathf.Clamp(radius * 2f, 6f, 24f);
			float num2 = Mathf.Clamp01(1f - Vector3.Distance(Player.Head.position, point) / num);
			if (!(num2 <= 0f))
			{
				Ensure();
				_trauma = Mathf.Clamp01(_trauma + 0.25f + num2 * 0.65f);
				_manager = Object.FindObjectOfType<Audio3dManager>();
				if (Object.op_Implicit((Object)(object)_ring))
				{
					_ring.outputAudioMixerGroup = Audio.InHead;
				}
				if (Object.op_Implicit((Object)(object)_ring) && !_ring.isPlaying)
				{
					_ring.Play();
				}
				BlastCount++;
			}
		}

		internal void ObserveCutoff(Audio3dManager manager, ref float cutoff)
		{
			if (!_writingCutoff)
			{
				_manager = manager;
				_baselineCutoff = cutoff;
				if (_trauma > 0f)
				{
					cutoff = Mathf.Min(cutoff, Mathf.Lerp(22000f, 900f, _trauma));
				}
			}
		}

		internal void Update()
		{
			if (_trauma <= 0f)
			{
				return;
			}
			if (!Settings.Enabled.Value || !Settings.Tinnitus.Value)
			{
				ResetHearing();
				return;
			}
			_trauma = Mathf.Max(0f, _trauma - Time.unscaledDeltaTime / 7f);
			if (Object.op_Implicit((Object)(object)_ring))
			{
				_ring.volume = Settings.RingVolume.Value * _trauma * _trauma;
			}
			WriteCutoff(Mathf.Min(_baselineCutoff, Mathf.Lerp(22000f, 900f, _trauma)));
			if (_trauma <= 0.001f)
			{
				ResetHearing();
			}
		}

		private void WriteCutoff(float value)
		{
			if (!Object.op_Implicit((Object)(object)_manager))
			{
				return;
			}
			_writingCutoff = true;
			try
			{
				_manager.SetLowPassFilter(value);
				_hasMuffled = true;
			}
			finally
			{
				_writingCutoff = false;
			}
		}

		internal void ResetHearing()
		{
			_trauma = 0f;
			if (Object.op_Implicit((Object)(object)_ring))
			{
				_ring.Stop();
			}
			if (_hasMuffled)
			{
				WriteCutoff(_baselineCutoff);
			}
			_hasMuffled = false;
		}

		internal void Clear()
		{
			ResetHearing();
			AudioSource[] voices = _voices;
			foreach (AudioSource val in voices)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.Stop();
				}
			}
			_manager = null;
			_baselineCutoff = 22000f;
			_lastBlast = -10f;
		}

		internal void Dispose()
		{
			Clear();
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
			}
			AudioClip[] drips = _drips;
			foreach (AudioClip val in drips)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
			drips = _cracks;
			foreach (AudioClip val2 in drips)
			{
				if (Object.op_Implicit((Object)(object)val2))
				{
					Object.Destroy((Object)(object)val2);
				}
			}
			if (Object.op_Implicit((Object)(object)_ringClip))
			{
				Object.Destroy((Object)(object)_ringClip);
			}
		}
	}
	internal static class BloodMaterial
	{
		internal static string ShaderName { get; private set; } = "not initialized";

		internal static Material Create(Texture? texture = null, bool unlit = false)
		{
			//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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_0247: 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)
			Shader val = null;
			string[] array = ((!unlit) ? new string[5] { "Universal Render Pipeline/Lit (PBR Workflow)", "Universal Render Pipeline/Lit", "Universal Render Pipeline/Particles/Unlit (Particles)", "Sprites/Default", "Unlit/Transparent" } : new string[4] { "Universal Render Pipeline/Particles/Unlit (Particles)", "Universal Render Pipeline/Particles/Unlit", "Sprites/Default", "Unlit/Transparent" });
			for (int i = 0; i < array.Length; i++)
			{
				Shader val2 = Shader.Find(array[i]);
				if (Object.op_Implicit((Object)(object)val2) && val2.isSupported)
				{
					val = val2;
					break;
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("No supported transparent blood shader is loaded. Blood effects have been disabled; see README.");
			}
			ShaderName = ((Object)val).name;
			Material val3 = new Material(val)
			{
				name = "Crimson blood",
				renderQueue = 3001
			};
			val3.SetOverrideTag("RenderType", "Transparent");
			Set(val3, "_Surface", 1f);
			Set(val3, "_Blend", 0f);
			Set(val3, "_Mode", 3f);
			Set(val3, "_SrcBlend", 5f);
			Set(val3, "_DstBlend", 10f);
			Set(val3, "_ZWrite", 0f);
			Set(val3, "_Cull", 0f);
			Set(val3, "_AlphaClip", 0f);
			Set(val3, "_Metallic", 0f);
			Set(val3, "_Smoothness", 0.54f);
			Set(val3, "_Glossiness", 0.54f);
			Set(val3, "_SmoothnessTextureChannel", 0f);
			Set(val3, "_ColorMode", 0f);
			Set(val3, "_OffsetFactor", -1f);
			Set(val3, "_OffsetUnits", -1f);
			Set(val3, "_SoftParticlesEnabled", 0f);
			Set(val3, "_CameraFadingEnabled", 0f);
			val3.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val3.EnableKeyword("_ALPHABLEND_ON");
			val3.DisableKeyword("_ALPHATEST_ON");
			val3.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			val3.DisableKeyword("_ALPHAMODULATE_ON");
			val3.DisableKeyword("_FADING_ON");
			val3.SetShaderPassEnabled("ShadowCaster", false);
			if (val3.HasProperty("_BaseColor"))
			{
				val3.SetColor("_BaseColor", Color.white);
			}
			if (val3.HasProperty("_Color"))
			{
				val3.SetColor("_Color", Color.white);
			}
			if (Object.op_Implicit((Object)(object)texture))
			{
				if (val3.HasProperty("_BaseMap"))
				{
					val3.SetTexture("_BaseMap", texture);
				}
				if (val3.HasProperty("_MainTex"))
				{
					val3.SetTexture("_MainTex", texture);
				}
			}
			return val3;
		}

		internal static Material SolidDroplet()
		{
			Material obj = Create();
			((Object)obj).name = "Crimson solid liquid";
			obj.renderQueue = 2000;
			obj.SetOverrideTag("RenderType", "Opaque");
			Set(obj, "_Surface", 0f);
			Set(obj, "_Mode", 0f);
			Set(obj, "_ZWrite", 1f);
			Set(obj, "_Cull", 2f);
			Set(obj, "_SrcBlend", 1f);
			Set(obj, "_DstBlend", 0f);
			Set(obj, "_OffsetFactor", 0f);
			Set(obj, "_OffsetUnits", 0f);
			Set(obj, "_Smoothness", 0.62f);
			Set(obj, "_Glossiness", 0.62f);
			obj.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
			obj.DisableKeyword("_ALPHABLEND_ON");
			return obj;
		}

		internal static void Set(Material mat, string property, float value)
		{
			if (mat.HasProperty(property))
			{
				mat.SetFloat(property, value);
			}
		}

		internal static void Tint(Material mat, Color color)
		{
			//IL_0013: 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)
			if (mat.HasProperty("_BaseColor"))
			{
				mat.SetColor("_BaseColor", color);
			}
			if (mat.HasProperty("_Color"))
			{
				mat.SetColor("_Color", color);
			}
		}
	}
	public sealed class BloodSimulation
	{
		private struct Drop
		{
			internal Vector3 Position;

			internal Vector3 Velocity;

			internal float Size;

			internal float VisualSize;

			internal float Age;

			internal int Owner;

			internal BloodKind Kind;
		}

		private sealed class Pool
		{
			internal Collider Collider;

			internal Vector3 LocalPoint;

			internal Vector3 LocalNormal;

			internal float Volume;

			internal float Radius;

			internal float Touched;

			internal float Next;

			internal int Seed;

			internal BloodKind Kind;
		}

		private readonly List<Drop> _drops = new List<Drop>(360);

		private readonly List<Pool> _pools = new List<Pool>(64);

		private readonly Il2CppStructArray<RaycastHit> _hits = new Il2CppStructArray<RaycastHit>(24L);

		private readonly SurfaceBlood _surface;

		private readonly AudioEffects _audio;

		private GameObject? _go;

		private Mesh? _mesh;

		private readonly Material?[] _materials = (Material?[])(object)new Material[4];

		private Il2CppStructArray<int>? _triangleBuffer;

		private readonly Vector3[] _vertices = (Vector3[])(object)new Vector3[360 * DropletShape.Vertices.Length];

		private readonly Vector3[] _normals = (Vector3[])(object)new Vector3[360 * DropletShape.Vertices.Length];

		private readonly int[] _indices = new int[360 * DropletShape.Indices.Length];

		private readonly Vector3[] _dropVertices = new Vector3[DropletShape.Vertices.Length];

		private readonly Vector3[] _dropNormals = new Vector3[DropletShape.Vertices.Length];

		internal int DropCount => _drops.Count;

		internal int PoolCount => _pools.Count;

		internal BloodSimulation(SurfaceBlood surface, AudioEffects audio)
		{
			_surface = surface;
			_audio = audio;
		}

		internal void Spray(Vector3 point, Vector3 direction, Vector3 normal, float damage, int owner, int? seed = null, BloodKind kind = BloodKind.Red, float amountScale = 1f)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			State state = Random.state;
			try
			{
				if (seed.HasValue)
				{
					Random.InitState(seed.Value);
				}
				SprayInternal(point, direction, normal, damage, owner, kind, amountScale);
			}
			finally
			{
				if (seed.HasValue)
				{
					Random.state = state;
				}
			}
		}

		private void SprayInternal(Vector3 point, Vector3 direction, Vector3 normal, float damage, int owner, BloodKind kind, float amountScale)
		{
			//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_0021: 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_006a: 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_0072: 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_0086: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Blood.Value)
			{
				if (((Vector3)(ref direction)).sqrMagnitude < 0.001f)
				{
					direction = -normal;
				}
				((Vector3)(ref direction)).Normalize();
				int num = HitBleeding.SprayCount(damage, Settings.Amount.Value, amountScale);
				float num2 = Random.Range(0.14f, 0.38f);
				float num3 = Random.Range(0.9f, 1.15f);
				for (int i = 0; i < num; i++)
				{
					Vector3 val = ((i % 5 == 0) ? normal : direction);
					Vector3 val2 = val + Random.insideUnitSphere * num2;
					Vector3 velocity = ((Vector3)(ref val2)).normalized * Random.Range(1.6f, 7.2f) * num3;
					float size = Mathf.Lerp(0.004f, 0.023f, Random.value * Random.value);
					Add(point + val * 0.025f, velocity, size, owner, kind, 0.7f);
				}
			}
		}

		internal void Drip(Vector3 point, int owner, bool small = false, BloodKind kind = BloodKind.Red)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			Add(point, Random.insideUnitSphere * 0.08f + Vector3.down * 0.1f, small ? 0.006f : Random.Range(0.009f, 0.016f), owner, kind);
		}

		internal void WoundSpray(Vector3 entry, Vector3? exit, Vector3 direction, Vector3 normal, float damage, int owner, int seed, BloodKind kind, Organ organ)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			float spray = HitBleeding.Profile(organ).Spray;
			Spray(entry, -direction, normal, damage, owner, seed, kind, spray);
			if (exit.HasValue)
			{
				Spray(exit.Value - direction * 0.003f, direction, direction, damage, owner, seed ^ 0x51A7, kind, spray);
			}
		}

		private void Add(Vector3 point, Vector3 velocity, float size, int owner, BloodKind kind, float visualScale = 1f)
		{
			//IL_0034: 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_003c: 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)
			if (Settings.Blood.Value && _drops.Count < Settings.MaxDrops.Value)
			{
				_drops.Add(new Drop
				{
					Position = point,
					Velocity = velocity,
					Size = size,
					VisualSize = size * visualScale,
					Owner = owner,
					Kind = kind
				});
			}
		}

		internal bool Trace(Vector3 from, Vector3 direction, float distance, int owner, out RaycastHit nearest)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			nearest = default(RaycastHit);
			float num = float.MaxValue;
			int num2 = Physics.RaycastNonAlloc(from, direction, _hits, distance, -5, (QueryTriggerInteraction)1);
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i];
				Collider collider = ((RaycastHit)(ref val)).collider;
				if (Object.op_Implicit((Object)(object)collider) && !(((RaycastHit)(ref val)).distance >= num) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<RigManager>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<MuscleCollisionBroadcaster>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<PuppetMaster>()))
				{
					nearest = val;
					num = ((RaycastHit)(ref val)).distance;
				}
			}
			return num < float.MaxValue;
		}

		internal void Smear(Vector3 point, int owner, float remaining, ref RaycastHit previous, ref bool hasContact, BloodKind kind = BloodKind.Red)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: 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_0058: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_0102: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if (!Trace(point + Vector3.up * 0.025f, Vector3.down, 0.16f, owner, out var nearest))
			{
				hasContact = false;
				return;
			}
			if (hasContact && (Object)(object)((RaycastHit)(ref previous)).collider == (Object)(object)((RaycastHit)(ref nearest)).collider && Vector3.Dot(((RaycastHit)(ref nearest)).normal, ((RaycastHit)(ref previous)).normal) > 0.96f)
			{
				Vector3 along = ((RaycastHit)(ref nearest)).point - ((RaycastHit)(ref previous)).point;
				float magnitude = ((Vector3)(ref along)).magnitude;
				if (magnitude > 0.012f && magnitude < 0.6f)
				{
					float num = Mathf.Clamp01(Object.op_Implicit((Object)(object)((RaycastHit)(ref nearest)).collider.sharedMaterial) ? ((RaycastHit)(ref nearest)).collider.sharedMaterial.dynamicFriction : 0.6f);
					int num2 = Mathf.Clamp(Mathf.CeilToInt(magnitude / 0.025f), 1, 16);
					RaycastHit hit = default(RaycastHit);
					for (int i = 0; i <= num2; i++)
					{
						Vector3 val = Vector3.Lerp(((RaycastHit)(ref previous)).point, ((RaycastHit)(ref nearest)).point, (float)i / (float)num2);
						if (!(Mathf.PerlinNoise(val.x * 41f, val.z * 41f) < num * 0.35f) && ((RaycastHit)(ref nearest)).collider.Raycast(new Ray(val + ((RaycastHit)(ref nearest)).normal * 0.04f, -((RaycastHit)(ref nearest)).normal), ref hit, 0.08f))
						{
							_surface.Paint(hit, Mathf.Lerp(0.012f, 0.045f, remaining) * (1f - 0.4f * num), 0.22f * remaining, along, 1.9f, owner, kind, BloodStampStyle.Smear);
						}
					}
				}
			}
			previous = nearest;
			hasContact = true;
		}

		internal void FixedUpdate()
		{
			//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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_007d: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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_00da: 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_00f2: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(Time.fixedDeltaTime, 0.04f);
			for (int num2 = _drops.Count - 1; num2 >= 0; num2--)
			{
				Drop value = _drops[num2];
				value.Age += num;
				ref Vector3 velocity = ref value.Velocity;
				velocity += Physics.gravity * num;
				ref Vector3 velocity2 = ref value.Velocity;
				velocity2 *= 1f - 0.15f * num;
				Vector3 val = value.Velocity * num;
				if (Trace(value.Position, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, value.Owner, out var nearest))
				{
					_surface.Paint(nearest, value.Size * Random.Range(1.2f, 2.7f), 0.65f, Vector3.ProjectOnPlane(value.Velocity, ((RaycastHit)(ref nearest)).normal), StainShape.ImpactStretch(Vector3.Dot(((Vector3)(ref value.Velocity)).normalized, ((RaycastHit)(ref nearest)).normal)), Random.Range(0, 9000), value.Kind);
					if (Random.value < 0.35f)
					{
						_audio.Drip(((RaycastHit)(ref nearest)).point);
					}
					if (Settings.Pools.Value && Vector3.Dot(((RaycastHit)(ref nearest)).normal, Vector3.up) > 0.72f)
					{
						Accumulate(nearest, value.Size * 13f, value.Kind);
					}
					_drops.RemoveAt(num2);
				}
				else
				{
					ref Vector3 position = ref value.Position;
					position += val;
					if (value.Age > 3f || num2 >= Settings.MaxDrops.Value)
					{
						_drops.RemoveAt(num2);
					}
					else
					{
						_drops[num2] = value;
					}
				}
			}
		}

		private void Accumulate(RaycastHit hit, float amount, BloodKind kind)
		{
			//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)
			//IL_001a: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Collider collider = ((RaycastHit)(ref hit)).collider;
			Vector3 localPoint = ((Component)collider).transform.InverseTransformPoint(((RaycastHit)(ref hit)).point);
			Pool pool = null;
			foreach (Pool pool2 in _pools)
			{
				if (pool2.Kind == kind && (Object)(object)pool2.Collider == (Object)(object)collider)
				{
					Vector3 val = ((Component)collider).transform.TransformPoint(pool2.LocalPoint) - ((RaycastHit)(ref hit)).point;
					if (((Vector3)(ref val)).sqrMagnitude < 0.025f)
					{
						pool = pool2;
						break;
					}
				}
			}
			if (pool == null)
			{
				if (_pools.Count >= 64)
				{
					_pools.RemoveAt(0);
				}
				pool = new Pool
				{
					Collider = collider,
					LocalPoint = localPoint,
					LocalNormal = ((Component)collider).transform.InverseTransformDirection(((RaycastHit)(ref hit)).normal),
					Seed = Random.Range(0, 9000),
					Kind = kind
				};
				_pools.Add(pool);
			}
			pool.Volume = Mathf.Min(32f, pool.Volume + amount);
			pool.Touched = Time.time;
		}

		internal void Update()
		{
			//IL_00c2: 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_00cc: 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_00e3: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00fc: 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_011a: 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)
			RaycastHit hit = default(RaycastHit);
			for (int num = _pools.Count - 1; num >= 0; num--)
			{
				Pool pool = _pools[num];
				if (!Object.op_Implicit((Object)(object)pool.Collider) || !((Component)pool.Collider).gameObject.activeInHierarchy || Time.time - pool.Touched > 12f || !Settings.Pools.Value)
				{
					_pools.RemoveAt(num);
				}
				else
				{
					pool.Radius = BloodField.Approach(pool.Radius, BloodField.PoolRadius(pool.Volume), 0.5f, Time.deltaTime);
					if (!(Time.time < pool.Next))
					{
						pool.Next = Time.time + 0.3f;
						Vector3 val = ((Component)pool.Collider).transform.TransformDirection(pool.LocalNormal);
						Vector3 val2 = ((Component)pool.Collider).transform.TransformPoint(pool.LocalPoint);
						if (pool.Collider.Raycast(new Ray(val2 + val * 0.05f, -val), ref hit, 0.1f))
						{
							_surface.Paint(hit, pool.Radius, 0.12f, Vector3.right, 1f, pool.Seed, pool.Kind, BloodStampStyle.Pool);
						}
					}
				}
			}
			DrawDrops();
		}

		private void EnsureMesh()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//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_0040: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_go))
			{
				return;
			}
			_go = new GameObject("Crimson airborne blood");
			_go.layer = 2;
			_mesh = new Mesh
			{
				name = "Crimson batched solid droplets"
			};
			_mesh.MarkDynamic();
			for (int i = 0; i < 4; i++)
			{
				_materials[i] = BloodMaterial.SolidDroplet();
				BloodSample bloodSample = BloodAppearance.Sample(1f, 1f, 1f, BloodPalette.Color((BloodKind)i));
				BloodMaterial.Tint(_materials[i], new Color(bloodSample.Red, bloodSample.Green, bloodSample.Blue));
			}
			_go.AddComponent<MeshFilter>().sharedMesh = _mesh;
			MeshRenderer obj = _go.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = Il2CppReferenceArray<Material>.op_Implicit(_materials);
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			for (int j = 0; j < 360; j++)
			{
				int num = j * DropletShape.Vertices.Length;
				int num2 = j * DropletShape.Indices.Length;
				for (int k = 0; k < DropletShape.Indices.Length; k++)
				{
					_indices[num2 + k] = num + DropletShape.Indices[k];
				}
			}
			_triangleBuffer = Il2CppStructArray<int>.op_Implicit(_indices);
			_mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(_vertices);
			_mesh.subMeshCount = 4;
		}

		private void DrawDrops()
		{
			//IL_004b: 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_0095: 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_0133: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if (_drops.Count == 0)
			{
				if (Object.op_Implicit((Object)(object)_go))
				{
					_go.SetActive(false);
				}
				return;
			}
			EnsureMesh();
			_go.SetActive(true);
			Array.Fill(_vertices, _drops[0].Position);
			int num = 0;
			for (int i = 0; i < 4; i++)
			{
				int num2 = num;
				foreach (Drop drop in _drops)
				{
					if ((int)drop.Kind == i)
					{
						DropletShape.Transform(NetworkEffects.N(drop.Position), NetworkEffects.N(drop.Velocity), drop.VisualSize, _dropVertices, _dropNormals);
						int num3 = num++ * DropletShape.Vertices.Length;
						for (int j = 0; j < DropletShape.Vertices.Length; j++)
						{
							Vector3 vector = _dropVertices[j];
							Vector3 vector2 = _dropNormals[j];
							_vertices[num3 + j] = new Vector3
							{
								x = vector.X,
								y = vector.Y,
								z = vector.Z
							};
							_normals[num3 + j] = new Vector3
							{
								x = vector2.X,
								y = vector2.Y,
								z = vector2.Z
							};
						}
					}
				}
				_mesh.SetTriangles(_triangleBuffer, num2 * DropletShape.Indices.Length, (num - num2) * DropletShape.Indices.Length, i, false, 0);
			}
			_mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(_vertices);
			_mesh.normals = Il2CppStructArray<Vector3>.op_Implicit(_normals);
			_mesh.RecalculateBounds();
		}

		internal void Clear()
		{
			_drops.Clear();
			_pools.Clear();
			if (Object.op_Implicit((Object)(object)_go))
			{
				Object.Destroy((Object)(object)_go);
			}
			if (Object.op_Implicit((Object)(object)_mesh))
			{
				Object.Destroy((Object)(object)_mesh);
			}
			for (int i = 0; i < _materials.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)_materials[i]))
				{
					Object.Destroy((Object)(object)_materials[i]);
				}
				_materials[i] = null;
			}
			_go = null;
			_mesh = null;
			_triangleBuffer = null;
		}
	}
	public sealed class CrimsonMod : MelonMod
	{
		internal static CrimsonMod? Instance;

		public readonly SurfaceBlood Surfaces = new SurfaceBlood();

		public readonly AudioEffects Audio = new AudioEffects();

		public BloodSimulation Blood;

		public NpcInjuries Npcs;

		internal PlayerBleeding Players;

		private bool _ready;

		private bool _visualFault;

		private readonly HashSet<string> _errors = new HashSet<string>();

		private readonly HashSet<(IntPtr Health, IntPtr Attack, int Muscle)> _seenHits = new HashSet<(IntPtr, IntPtr, int)>();

		private int _hitFrame = -1;

		internal int HealthEvents;

		internal int ContactEvents;

		internal int BloodSurfaceEvents;

		internal bool Ready
		{
			get
			{
				if (_ready)
				{
					return !_visualFault;
				}
				return false;
			}
		}

		public override void OnInitializeMelon()
		{
			Instance = this;
			Blood = new BloodSimulation(Surfaces, Audio);
			Npcs = new NpcInjuries(Blood, Surfaces, Audio);
			Players = new PlayerBleeding(Blood);
			Settings.Initialize();
			Hooking.OnLevelLoaded += LevelLoaded;
			Hooking.OnLevelLoading += LevelLoading;
			_ready = true;
			((MelonBase)this).LoggerInstance.Msg("Crimson 1.1.8 initialized. NPC and player blood; stock Marrow blood suppression enabled by default.");
			string[] array = (from m in MelonTypeBase<MelonMod>.RegisteredMelons
				where (object)m != this && new string[4] { "Blood", "Injur", "Ragdoll", "NPCPhysics" }.Any((string s) => ((MelonBase)m).Info.Name.Contains(s, StringComparison.OrdinalIgnoreCase))
				select ((MelonBase)m).Info.Name).ToArray();
			if (array.Length != 0)
			{
				((MelonBase)this).LoggerInstance.Warning("Overlapping effects/physics mods found: " + string.Join(", ", array) + ". Use Crimson feature toggles if effects conflict.");
			}
		}

		private void LevelLoading(LevelInfo info)
		{
			_ready = false;
			Clear();
		}

		private void LevelLoaded(LevelInfo info)
		{
			_ready = true;
			_visualFault = false;
		}

		public override void OnUpdate()
		{
			if (!_ready)
			{
				return;
			}
			try
			{
				Audio.Update();
			}
			catch (Exception error)
			{
				Report("audio update", error);
				Audio.ResetHearing();
			}
			if (!Settings.Enabled.Value)
			{
				return;
			}
			try
			{
				Npcs.Update();
			}
			catch (Exception error2)
			{
				Report("NPC injury update", error2);
			}
			try
			{
				Players.Update();
			}
			catch (Exception error3)
			{
				Report("player blood update", error3);
			}
			try
			{
				VanillaBlood.Update();
			}
			catch (Exception error4)
			{
				Report("stock blood removal", error4);
			}
			if (!Settings.Blood.Value || _visualFault)
			{
				return;
			}
			try
			{
				Blood.Update();
				Surfaces.Update();
			}
			catch (Exception error5)
			{
				_visualFault = true;
				Report("blood rendering (disabled until next level)", error5);
				ClearBlood();
			}
		}

		public override void OnFixedUpdate()
		{
			if (!_ready || !Settings.Enabled.Value || !Settings.Blood.Value || _visualFault)
			{
				return;
			}
			try
			{
				Blood.FixedUpdate();
			}
			catch (Exception error)
			{
				Report("droplet simulation", error);
			}
		}

		internal bool Hit(SubBehaviourHealth health, int index, Attack attack, bool hasBloodSurface = false, BloodKind? bloodKind = null)
		{
			if (!_ready || health == null || attack == null)
			{
				return false;
			}
			if (_hitFrame != Time.frameCount)
			{
				_seenHits.Clear();
				_hitFrame = Time.frameCount;
			}
			(IntPtr, IntPtr, int) item = (((Il2CppObjectBase)health).Pointer, ((Il2CppObjectBase)attack).Pointer, index);
			if (_seenHits.Contains(item))
			{
				return true;
			}
			try
			{
				if (!Npcs.Hit(health, index, attack, hasBloodSurface, remote: false, null, bloodKind))
				{
					return false;
				}
				_seenHits.Add(item);
				return true;
			}
			catch (Exception error)
			{
				Report("damage hook", error);
				return false;
			}
		}

		internal bool Contact(MuscleCollisionBroadcaster broadcaster, Attack attack, bool hasBloodSurface = false, BloodKind? bloodKind = null)
		{
			ContactEvents++;
			if (!_ready || !Object.op_Implicit((Object)(object)broadcaster) || attack == null)
			{
				return false;
			}
			try
			{
				PuppetMaster puppetMaster = broadcaster.puppetMaster;
				if (!Object.op_Implicit((Object)(object)puppetMaster) || puppetMaster.behaviours == null)
				{
					return false;
				}
				foreach (BehaviourBase item in (Il2CppArrayBase<BehaviourBase>)(object)puppetMaster.behaviours)
				{
					BehaviourBaseNav val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<BehaviourBaseNav>() : null);
					if (((val != null) ? val.health : null) != null)
					{
						return Hit(val.health, broadcaster.muscleIndex, attack, hasBloodSurface, bloodKind);
					}
				}
			}
			catch (Exception error)
			{
				Report("NPC contact hook", error);
			}
			return false;
		}

		internal void BloodImpact(ImpactProperties impact, Attack attack)
		{
			//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_00fa: 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_0125: 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_0109: 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_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_017f: 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_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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if (!_ready || !Settings.Enabled.Value || !Settings.Blood.Value || attack == null || !VanillaBlood.IsBlood(impact))
			{
				return;
			}
			BloodSurfaceEvents++;
			try
			{
				MuscleCollisionBroadcaster componentInParent = ((Component)impact).GetComponentInParent<MuscleCollisionBroadcaster>();
				NpcBlood.TryImpact(impact, out var kind);
				if (Object.op_Implicit((Object)(object)componentInParent) && Contact(componentInParent, attack, hasBloodSurface: true, kind))
				{
					return;
				}
				PlayerDamageReceiver componentInParent2 = ((Component)impact).GetComponentInParent<PlayerDamageReceiver>();
				if (!Object.op_Implicit((Object)(object)componentInParent2) && Object.op_Implicit((Object)(object)attack.collider))
				{
					componentInParent2 = ((Component)attack.collider).GetComponentInParent<PlayerDamageReceiver>();
				}
				if (Object.op_Implicit((Object)(object)componentInParent2) && Players.Hit(componentInParent2, attack))
				{
					return;
				}
				if (_hitFrame != Time.frameCount)
				{
					_seenHits.Clear();
					_hitFrame = Time.frameCount;
				}
				if (!_seenHits.Add((((Il2CppObjectBase)impact).Pointer, ((Il2CppObjectBase)attack).Pointer, -1)))
				{
					return;
				}
				Vector3 val = attack.origin;
				if (!FaceFinite(val) || Vector3.Distance(val, ((Component)impact).transform.position) > 1f)
				{
					val = ((Component)impact).transform.position;
				}
				Vector3 val2;
				Vector3 val3;
				if (FaceFinite(attack.direction))
				{
					val2 = attack.direction;
					if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
					{
						val2 = attack.direction;
						val3 = ((Vector3)(ref val2)).normalized;
						goto IL_016a;
					}
				}
				val3 = -((Component)impact).transform.forward;
				goto IL_016a;
				IL_01a7:
				Vector3 val4;
				Vector3 normal = (Vector3)val4;
				int num = Random.Shared.Next();
				float damage = (float.IsFinite(attack.damage) ? Mathf.Max(1f, attack.damage) : 1f);
				Vector3 val5;
				Blood.Spray(val, val5, normal, damage, ((Object)impact).GetInstanceID(), num, kind);
				NetworkEffects.Splash(val, val5, normal, damage, num, kind);
				return;
				IL_016a:
				val5 = val3;
				if (FaceFinite(attack.normal))
				{
					val2 = attack.normal;
					if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
					{
						val2 = attack.normal;
						val4 = ((Vector3)(ref val2)).normalized;
						goto IL_01a7;
					}
				}
				val4 = -val5;
				goto IL_01a7;
			}
			catch (Exception error)
			{
				Report("blood surface hook", error);
			}
		}

		private static bool FaceFinite(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (float.IsFinite(v.x) && float.IsFinite(v.y))
			{
				return float.IsFinite(v.z);
			}
			return false;
		}

		internal void TestBlood()
		{
			//IL_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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)
			Transform head = Player.Head;
			if (!_ready || !Object.op_Implicit((Object)(object)head) || !Settings.Enabled.Value || !Settings.Blood.Value)
			{
				((MelonBase)this).LoggerInstance.Msg("Test blood: enter a level and enable Crimson and Blood spray first.");
				return;
			}
			_visualFault = false;
			Blood.Spray(head.position + head.forward * 0.7f - head.up * 0.15f, Vector3.down, head.forward, 18f, 0);
			((MelonBase)this).LoggerInstance.Msg("Test blood spawned in front of the headset. Use Print diagnostics after it lands.");
		}

		public void ClearBlood()
		{
			Blood.Clear();
			Surfaces.Clear();
		}

		public void Clear()
		{
			Npcs.Clear();
			Players.Clear();
			ClearBlood();
			Audio.Clear();
			VanillaBlood.Clear();
			NetworkEffects.Clear();
			_seenHits.Clear();
		}

		internal void Diagnostics()
		{
			((MelonBase)this).LoggerInstance.Msg($"ready={_ready}, enabled={Settings.Enabled.Value}, blood={Settings.Blood.Value}, playerBlood={Settings.PlayerBlood.Value}; healthEvents={HealthEvents}, contactEvents={ContactEvents}, bloodSurfaceEvents={BloodSurfaceEvents}, npcHits={Npcs.HitCount}, playerHits={Players.Hits}, fractures={Npcs.FractureCount}, blasts={Audio.BlastCount}; stockImpactsBlocked={VanillaBlood.ImpactsSuppressed}, stockWoundsBlocked={VanillaBlood.WoundsSuppressed}, stockDecalsBlocked={VanillaBlood.DecalsSuppressed}, stockPoolsBlocked={VanillaBlood.PooledEffectsSuppressed}; NPCs={Npcs.Count}, drops={Blood.DropCount}, pools={Blood.PoolCount}, tiles={Surfaces.Count}, queued={Surfaces.Queued}; shader={BloodMaterial.ShaderName}; visualFault={_visualFault}");
			((MelonBase)this).LoggerInstance.Msg("Fusion sharing=" + Settings.Fusion.Value + "; " + (NetworkEffects.Transport?.Status ?? "CrimsonFusion.dll not loaded"));
			((MelonBase)this).LoggerInstance.Msg($"Wound zones: lastNpcOrgan={Npcs.LastOrgan}, lastPlayerOrgan={Players.LastOrgan}; npcExitHits={Npcs.ExitHits}, playerExitHits={Players.ExitHits}. Organ zones and exits are cosmetic approximations.");
		}

		internal static void Report(string context, Exception error)
		{
			if (Instance != null && Instance._errors.Add(context))
			{
				((MelonBase)Instance).LoggerInstance.Error(context + ": " + error);
			}
		}

		public override void OnDeinitializeMelon()
		{
			_ready = false;
			Hooking.OnLevelLoaded -= LevelLoaded;
			Hooking.OnLevelLoading -= LevelLoading;
			Clear();
			Audio.Dispose();
			Instance = null;
		}
	}
	public static class CrimsonApi
	{
		public static void NotifyExplosion(Vector3 position, float blastRadius = 8f)
		{
			//IL_0000: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsFinite(position.x + position.y + position.z + blastRadius) || blastRadius <= 0f)
			{
				return;
			}
			try
			{
				NetworkEffects.LocalBlast(position, blastRadius);
			}
			catch (Exception error)
			{
				CrimsonMod.Report("explosion hook", error);
			}
		}
	}
	[HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")]
	internal static class DamagePatch
	{
		[HarmonyPriority(800)]
		private static void Prefix(SubBehaviourHealth __instance, int m, Attack attack)
		{
			if (CrimsonMod.Instance != null)
			{
				CrimsonMod.Instance.HealthEvents++;
				CrimsonMod.Instance.Hit(__instance, m, attack);
			}
		}
	}
	[HarmonyPatch(typeof(MuscleCollisionBroadcaster), "ReceiveAttack")]
	internal static class NpcContactPatch
	{
		[HarmonyPriority(800)]
		private static void Prefix(MuscleCollisionBroadcaster __instance, Attack attack)
		{
			CrimsonMod.Instance?.Contact(__instance, attack);
		}
	}
	[HarmonyPatch(typeof(PuppetMaster), "OnPoolSpawn")]
	internal static class RespawnPatch
	{
		private static void Prefix(PuppetMaster __instance)
		{
			CrimsonMod.Instance?.Npcs.Reset(__instance);
		}
	}
	[HarmonyPatch(typeof(PuppetMaster), "OnDisable")]
	internal static class DespawnPatch
	{
		private static void Prefix(PuppetMaster __instance)
		{
			CrimsonMod.Instance?.Npcs.Reset(__instance);
		}
	}
	[HarmonyPatch(typeof(BehaviourBaseNav), "Resurrect")]
	internal static class ResurrectPatch
	{
		private static void Prefix(BehaviourBaseNav __instance)
		{
			if (Object.op_Implicit((Object)(object)((BehaviourBase)__instance).puppetMaster))
			{
				CrimsonMod.Instance?.Npcs.Reset(((BehaviourBase)__instance).puppetMaster);
			}
		}
	}
	[HarmonyPatch(typeof(Muscle), "MusclePdDrive")]
	internal static class JointDrivePatch
	{
		private static void Prefix(Muscle __instance, ref float muscleWeightMaster)
		{
			CrimsonMod? instance = CrimsonMod.Instance;
			if (instance != null && instance.Npcs.BrokenMuscles.Contains(((Il2CppObjectBase)__instance).Pointer) && Settings.Enabled.Value && Settings.Breaks.Value)
			{
				muscleWeightMaster = FractureRules.Drive(muscleWeightMaster);
			}
		}
	}
	[HarmonyPatch(typeof(SimpleExplosionForce), "OnEnable")]
	internal static class ExplosionPatch
	{
		private static void Postfix(SimpleExplosionForce __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			CrimsonApi.NotifyExplosion(((Component)__instance).transform.position, Mathf.Abs(__instance.radius));
		}
	}
	[HarmonyPatch(typeof(Arena_Bomb), "ExplodeBomb")]
	internal static class ArenaExplosionPatch
	{
		private static void Prefix(Arena_Bomb __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			CrimsonApi.NotifyExplosion(((Component)__instance).transform.position);
		}
	}
	[HarmonyPatch(typeof(Audio3dManager), "SetLowPassFilter")]
	internal static class MufflePatch
	{
		private static void Prefix(Audio3dManager __instance, ref float lpf)
		{
			CrimsonMod.Instance?.Audio.ObserveCutoff(__instance, ref lpf);
		}
	}
	internal static class HitAnatomy
	{
		internal static Organ Npc(PuppetMaster puppet, Muscle muscle, Vector3 entry, Vector3 end)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_003a: Expected I4, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Group val = muscle.props.group;
			Animator animator;
			switch ((int)val)
			{
			case 2:
				return Organ.Brain;
			case 3:
			case 5:
			case 7:
				return Organ.SoftTissue;
			case 4:
			case 6:
				return Organ.Extremity;
			default:
				return Organ.Unknown;
			case 0:
			case 1:
				animator = puppet.targetAnimator;
				if (!Object.op_Implicit((Object)(object)animator) || !animator.isHuman)
				{
					return Organ.Unknown;
				}
				return Torso(Live((HumanBodyBones)0), Live((HumanBodyBones)10), Live((HumanBodyBones)13), Live((HumanBodyBones)14), entry, end);
			}
			Transform? Live(HumanBodyBones bone)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Transform boneTransform = animator.GetBoneTransform(bone);
				if (!Object.op_Implicit((Object)(object)boneTransform))
				{
					return null;
				}
				foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
				{
					if (item != null && (Object)(object)item.target == (Object)(object)boneTransform && Object.op_Implicit((Object)(object)item.transform))
					{
						return item.transform;
					}
				}
				return boneTransform;
			}
		}

		internal static Organ Player(RigManager rig, HumanBodyBones bone, Vector3 entry, Vector3 end)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_002d: 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_005f: 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_0032: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			if ((int)bone == 10)
			{
				return Organ.Brain;
			}
			if ((int)bone == 9)
			{
				return Organ.Neck;
			}
			if ((int)bone == 17 || (int)bone == 18 || (int)bone == 5 || (int)bone == 6 || (int)bone == 19 || (int)bone == 20)
			{
				return Organ.Extremity;
			}
			if ((int)bone != 0 && (int)bone != 7 && (int)bone != 8 && (int)bone != 54)
			{
				return Organ.SoftTissue;
			}
			return Torso(PlayerBleeding.Bone(rig, (HumanBodyBones)0), PlayerBleeding.Bone(rig, (HumanBodyBones)10), PlayerBleeding.Bone(rig, (HumanBodyBones)13), PlayerBleeding.Bone(rig, (HumanBodyBones)14), entry, end);
		}

		private static Organ Torso(Transform? hips, Transform? head, Transform? left, Transform? right, Vector3 entry, Vector3 end)
		{
			//IL_0023: 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_003b: 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_0046: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)hips) || !Object.op_Implicit((Object)(object)head) || !Object.op_Implicit((Object)(object)left) || !Object.op_Implicit((Object)(object)right))
			{
				return Organ.Unknown;
			}
			Vector3 hips2 = NetworkEffects.N(hips.position);
			if (!HitBleeding.TryFrame(hips2, NetworkEffects.N(head.position), NetworkEffects.N(right.position - left.position), out var up, out var right2, out var forward, out var height))
			{
				return Organ.Unknown;
			}
			return HitBleeding.AlongPath(HitBleeding.BodyPoint(NetworkEffects.N(entry), hips2, up, right2, forward, height), HitBleeding.BodyPoint(NetworkEffects.N(end), hips2, up, right2, forward, height));
		}

		internal static bool Exit(Collider? collider, Vector3 entry, Vector3 direction, out Vector3 exit)
		{
			//IL_0001: 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_0030: 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_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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00b8: 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_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)
			exit = default(Vector3);
			if (!Object.op_Implicit((Object)(object)collider) || collider.isTrigger || !collider.enabled || !((Component)collider).gameObject.activeInHierarchy)
			{
				return false;
			}
			Vector3 val = collider.ClosestPoint(entry) - entry;
			if (((Vector3)(ref val)).sqrMagnitude > 0.0009f)
			{
				return false;
			}
			direction = ((Vector3)(ref direction)).normalized;
			Bounds bounds = collider.bounds;
			val = ((Bounds)(ref bounds)).size;
			float num = Mathf.Clamp(((Vector3)(ref val)).magnitude + 0.1f, 0.1f, 6f);
			RaycastHit val2 = default(RaycastHit);
			if (!collider.Raycast(new Ray(entry + direction * num, -direction), ref val2, num))
			{
				return false;
			}
			if (!HitBleeding.ValidExit(NetworkEffects.N(entry), NetworkEffects.N(((RaycastHit)(ref val2)).point), NetworkEffects.N(direction), NetworkEffects.N(((RaycastHit)(ref val2)).normal), num))
			{
				return false;
			}
			exit = ((RaycastHit)(ref val2)).point;
			return true;
		}

		internal static Vector3? NpcExit(Muscle muscle, Vector3 entry, Vector3 direction)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (muscle.colliders == null)
			{
				return null;
			}
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)muscle.colliders)
			{
				if (Exit(item, entry, direction, out var exit))
				{
					return exit;
				}
			}
			return null;
		}

		internal static Vector3? PlayerExit(RigManager rig, HumanBodyBones bone, Vector3 entry, Vector3 direction)
		{
			//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_003f: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			foreach (PlayerDamageReceiver componentsInChild in ((Component)rig).GetComponentsInChildren<PlayerDamageReceiver>())
			{
				if (!Object.op_Implicit((Object)(object)componentsInChild) || PlayerBleeding.BodyBone(componentsInChild.bodyPart) != bone)
				{
					continue;
				}
				foreach (Collider componentsInChild2 in ((Component)componentsInChild).GetComponentsInChildren<Collider>())
				{
					if (Exit(componentsInChild2, entry, direction, out var exit))
					{
						return exit;
					}
				}
			}
			return null;
		}
	}
	internal interface ICrimsonNetwork
	{
		bool Active { get; }

		string Status { get; }

		bool CanControl(PuppetMaster puppet);

		void Send(EffectPacket packet, PuppetMaster? puppet);

		void SendPlayer(EffectPacket packet, RigManager rig);
	}
	internal static class NetworkEffects
	{
		internal static ICrimsonNetwork? Transport;

		private static readonly Queue<(EffectKind Kind, Vector3 Point, float At)> RecentWorld = new Queue<(EffectKind, Vector3, float)>();

		internal static bool Active
		{
			get
			{
				if (Settings.Fusion != null && Settings.Fusion.Value)
				{
					return Transport?.Active ?? false;
				}
				return false;
			}
		}

		private static bool FirstWorld(EffectKind kind, Vector3 point)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			while (RecentWorld.Count > 0 && Time.unscaledTime - RecentWorld.Peek().At > 0.6f)
			{
				RecentWorld.Dequeue();
			}
			if (RecentWorld.Any(delegate((EffectKind Kind, Vector3 Point, float At) e)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if (e.Kind == kind)
				{
					Vector3 val = e.Point - point;
					return ((Vector3)(ref val)).sqrMagnitude < 0.0004f;
				}
				return false;
			}))
			{
				return false;
			}
			if (RecentWorld.Count >= 128)
			{
				RecentWorld.Dequeue();
			}
			RecentWorld.Enqueue((kind, point, Time.unscaledTime));
			return true;
		}

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

		internal static bool CanControl(PuppetMaster puppet)
		{
			if (Transport == null)
			{
				return true;
			}
			try
			{
				return Transport.CanControl(puppet);
			}
			catch (Exception error)
			{
				CrimsonMod.Report("Fusion authority", error);
				return false;
			}
		}

		internal static void Send(EffectPacket packet, PuppetMaster? puppet = null)
		{
			if (!Active)
			{
				return;
			}
			try
			{
				Transport.Send(packet, puppet);
			}
			catch (Exception error)
			{
				CrimsonMod.Report("Fusion send", error);
			}
		}

		internal static void Hit(PuppetMaster puppet, int muscle, Vector3 point, Vector3 direction, Vector3 normal, float damage, int attackType, int seed, BloodKind kind, Organ organ, Vector3? exit)
		{
			//IL_0059: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			Send(new EffectPacket
			{
				Kind = EffectKind.Hit,
				Muscle = (ushort)muscle,
				Flags = 1,
				Blood = kind,
				Organ = organ,
				HasExit = exit.HasValue,
				ExitPoint = (exit.HasValue ? N(exit.Value) : default(Vector3)),
				Point = N(point),
				Direction = N(direction),
				Normal = N(normal),
				Amount = Mathf.Clamp(damage, 0f, 500f),
				AttackType = attackType,
				Seed = seed
			}, puppet);
		}

		internal static void Splash(Vector3 point, Vector3 direction, Vector3 normal, float damage, int seed, BloodKind kind)
		{
			//IL_0001: 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_0030: 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)
			FirstWorld(EffectKind.Splash, point);
			Send(new EffectPacket
			{
				Kind = EffectKind.Splash,
				Blood = kind,
				Point = N(point),
				Direction = N(direction),
				Normal = N(normal),
				Amount = Mathf.Clamp(damage, 0f, 500f),
				Seed = seed
			});
		}

		internal static void Crack(PuppetMaster puppet, Vector3 point)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Send(new EffectPacket
			{
				Kind = EffectKind.Crack,
				Point = N(point)
			}, puppet);
		}

		internal static void Blast(Vector3 point, float radius)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Send(new EffectPacket
			{
				Kind = EffectKind.Blast,
				Point = N(point),
				Amount = Mathf.Clamp(radius, 0.1f, 100f)
			});
		}

		internal static void LocalBlast(Vector3 point, float radius)
		{
			//IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			if (FirstWorld(EffectKind.Blast, point))
			{
				CrimsonMod.Instance?.Audio.Explosion(point, radius);
				Blast(point, radius);
			}
		}

		internal static void PlayerHit(RigManager rig, HumanBodyBones bone, Vector3 point, Vector3 direction, Vector3 normal, float damage, int seed, int attackType, Organ organ, Vector3? exit)
		{
			//IL_0020: 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_006c: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			if (!Active)
			{
				return;
			}
			try
			{
				Transport.SendPlayer(new EffectPacket
				{
					Kind = EffectKind.PlayerHit,
					Muscle = (ushort)bone,
					Point = N(point),
					AttackType = attackType,
					Organ = organ,
					HasExit = exit.HasValue,
					ExitPoint = (exit.HasValue ? N(exit.Value) : default(Vector3)),
					Direction = N(direction),
					Normal = N(normal),
					Amount = Mathf.Clamp(damage, 0f, 500f),
					Seed = seed
				}, rig);
			}
			catch (Exception error)
			{
				CrimsonMod.Report("Fusion player blood", error);
			}
		}

		internal static void Apply(EffectPacket packet, PuppetMaster? puppet)
		{
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: 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_022b: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e6: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0138: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			CrimsonMod instance = CrimsonMod.Instance;
			if (instance == null || !instance.Ready || !Settings.Enabled.Value)
			{
				return;
			}
			switch (packet.Kind)
			{
			case EffectKind.Hit:
			{
				if (!Object.op_Implicit((Object)(object)puppet) || puppet.muscles == null || packet.Muscle >= ((Il2CppArrayBase<Muscle>)(object)puppet.muscles).Length)
				{
					break;
				}
				Muscle val = ((Il2CppArrayBase<Muscle>)(object)puppet.muscles)[(int)packet.Muscle];
				if (val == null || !Object.op_Implicit((Object)(object)val.transform) || puppet.behaviours == null)
				{
					break;
				}
				{
					foreach (BehaviourBase item in (Il2CppArrayBase<BehaviourBase>)(object)puppet.behaviours)
					{
						BehaviourBaseNav val2 = ((item != null) ? ((Il2CppObjectBase)item).TryCast<BehaviourBaseNav>() : null);
						if (((val2 != null) ? val2.health : null) != null)
						{
							Attack attack = new Attack
							{
								origin = val.transform.TransformPoint(U(packet.Point)),
								direction = val.transform.TransformDirection(U(packet.Direction)),
								normal = val.transform.TransformDirection(U(packet.Normal)),
								damage = packet.Amount,
								attackType = (AttackType)packet.AttackType
							};
							instance.Npcs.Hit(val2.health, packet.Muscle, attack, hasBloodSurface: true, remote: true, packet.Seed, packet.Blood, packet.Organ, packet.HasExit ? new Vector3?(val.transform.TransformPoint(U(packet.ExitPoint))) : ((Vector3?)null));
							break;
						}
					}
					break;
				}
			}
			case EffectKind.Splash:
				if (FirstWorld(EffectKind.Splash, U(packet.Point)))
				{
					if (packet.Organ != Organ.Unknown || packet.HasExit)
					{
						instance.Blood.WoundSpray(U(packet.Point), packet.HasExit ? new Vector3?(U(packet.ExitPoint)) : ((Vector3?)null), U(packet.Direction), U(packet.Normal), packet.Amount, 0, packet.Seed, packet.Blood, packet.Organ);
					}
					else
					{
						instance.Blood.Spray(U(packet.Point), U(packet.Direction), U(packet.Normal), packet.Amount, 0, packet.Seed, packet.Blood);
					}
				}
				break;
			case EffectKind.Crack:
				if (Settings.Breaks.Value)
				{
					instance.Audio.Crack(U(packet.Point));
				}
				break;
			case EffectKind.Blast:
				if (FirstWorld(EffectKind.Blast, U(packet.Point)))
				{
					instance.Audio.Explosion(U(packet.Point), packet.Amount);
				}
				break;
			}
		}

		internal static Vector3 N(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(v.x, v.y, v.z);
		}

		internal static Vector3 U(Vector3 v)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(v.X, v.Y, v.Z);
		}
	}
	internal static class NpcBlood
	{
		private static readonly Dictionary<int, (PuppetMaster Puppet, bool Known, BloodKind Kind)> Cache = new Dictionary<int, (PuppetMaster, bool, BloodKind)>();

		internal static bool TryImpact(ImpactProperties impact, out BloodKind kind)
		{
			kind = BloodKind.Red;
			if (!Object.op_Implicit((Object)(object)impact))
			{
				return false;
			}
			SurfaceData val = (Object.op_Implicit((Object)(object)impact.surfaceData) ? impact.surfaceData : impact._cachedSurfaceData);
			DataCardReference<SurfaceDataCard> surfaceDataCard = impact.SurfaceDataCard;
			object barcode;
			if (surfaceDataCard == null)
			{
				barcode = null;
			}
			else
			{
				Barcode barcode2 = ((ScannableReference)surfaceDataCard).Barcode;
				barcode = ((barcode2 != null) ? barcode2.ID : null);
			}
			return BloodPalette.TrySurface((string?)barcode, Object.op_Implicit((Object)(object)val) ? ((Object)val).name : null, out kind);
		}

		internal static bool Resolve(PuppetMaster puppet, Muscle muscle, Collider collider, out BloodKind kind)
		{
			if (Object.op_Implicit((Object)(object)collider) && ((Component)collider).transform.IsChildOf(((Component)puppet).transform) && TryImpact(((Component)collider).GetComponentInParent<ImpactProperties>(), out kind))
			{
				return true;
			}
			if (muscle.colliders != null)
			{
				foreach (Collider item in (Il2CppArrayBase<Collider>)(object)muscle.colliders)
				{
					if (Object.op_Implicit((Object)(object)item) && TryImpact(((Component)item).GetComponentInParent<ImpactProperties>(), out kind))
					{
						return true;
					}
				}
			}
			int instanceID = ((Object)puppet).GetInstanceID();
			if (Cache.TryGetValue(instanceID, out (PuppetMaster, bool, BloodKind) value) && (Object)(object)value.Item1 == (Object)(object)puppet)
			{
				kind = value.Item3;
				return value.Item2;
			}
			bool flag = false;
			kind = BloodKind.Red;
			foreach (ImpactProperties componentsInChild in ((Component)puppet).GetComponentsInChildren<ImpactProperties>(true))
			{
				if (TryImpact(componentsInChild, out var kind2))
				{
					flag = true;
					kind = kind2;
					if (kind2 != BloodKind.Red)
					{
						break;
					}
				}
			}
			if (Cache.Count >= 128)
			{
				Cache.Clear();
			}
			if (flag)
			{
				Cache[instanceID] = (puppet, true, kind);
			}
			return flag;
		}

		internal static void Reset(PuppetMaster puppet)
		{
			if (Object.op_Implicit((Object)(object)puppet))
			{
				Cache.Remove(((Object)puppet).GetInstanceID());
			}
		}

		internal static void Clear()
		{
			Cache.Clear();
		}
	}
	public sealed class NpcInjuries
	{
		private sealed class Wound
		{
			internal Transform Anchor;

			internal Vector3 LocalPoint;

			internal float Started;

			internal float Expires;

			internal float NextDrip;

			internal float NextSmear;

			internal bool HasContact;

			internal RaycastHit Previous;

			internal BloodKind Kind;

			internal Organ Organ;

			internal Vector3 ExitPoint;

			internal bool HasExit;

			internal bool ExitContact;

			internal RaycastHit ExitPrevious;
		}

		private sealed class Fracture
		{
			internal Muscle Muscle;
		}

		private sealed class Actor
		{
			internal PuppetMaster Puppet;

			internal readonly List<Wound> Wounds = new List<Wound>(4);

			internal readonly Dictionary<int, float> Damage = new Dictionary<int, float>();

			internal readonly Dictionary<int, Fracture> Fractures = new Dictionary<int, Fracture>();

			internal float Touched;

			internal int LastFrame = -1;

			internal readonly Dictionary<int, Vector3> Contacts = new Dictionary<int, Vector3>();
		}

		private readonly Dictionary<int, Actor> _actors = new Dictionary<int, Actor>();

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

		private readonly BloodSimulation _blood;

		private readonly SurfaceBlood _surface;

		private readonly AudioEffects _audio;

		internal readonly HashSet<IntPtr> BrokenMuscles = new HashSet<IntPtr>();

		internal int Count => _actors.Count;

		internal int HitCount { get; private set; }

		internal int FractureCount { get; private set; }

		internal int ExitHits { get; private set; }

		internal Organ LastOrgan { get; private set; }

		internal NpcInjuries(BloodSimulation blood, SurfaceBlood surface, AudioEffects audio)
		{
			_blood = blood;
			_surface = surface;
			_audio = audio;
		}

		internal bool Hit(SubBehaviourHealth health, int index, Attack attack, bool hasBloodSurface = false, bool remote = false, int? seed = null, BloodKind? bloodKind = null, Organ? organ = null, Vector3? exitPoint = null)
		{
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: 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_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Invalid comparison between Unknown and I4
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Invalid comparison between Unknown and I4
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Invalid comparison between Unknown and I4
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Expected I4, but got Unknown
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Invalid comparison between Unknown and I4
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Invalid comparison between Unknown and I4
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Invalid comparison between Unknown and I4
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Invalid comparison between Unknown and I4
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Invalid comparison between Unknown and I4
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Invalid comparison between Unknown and I4
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Invalid comparison between Unknown and I4
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Invalid comparison between Unknown and I4
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Invalid comparison between Unknown and I4
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.Enabled.Value || attack == null || !float.IsFinite(attack.damage) || attack.damage <= 0.1f)
			{
				return false;
			}
			BehaviourBase behaviour = ((SubBehaviourBase)health).behaviour;
			if (!Object.op_Implicit((Object)(object)behaviour) || !Object.op_Implicit((Object)(object)behaviour.puppetMaster))
			{
				return false;
			}
			PuppetMaster puppetMaster = behaviour.puppetMaster;
			if (!remote && NetworkEffects.Active && !NetworkEffects.CanControl(puppetMaster))
			{
				return true;
			}
			if (!((Component)puppetMaster).gameObject.activeInHierarchy || !puppetMaster.initiated || puppetMaster.muscles == null || index < 0 || index >= ((Il2CppArrayBase<Muscle>)(object)puppetMaster.muscles).Length)
			{
				return false;
			}
			Muscle val = ((Il2CppArrayBase<Muscle>)(object)puppetMaster.muscles)[index];
			if (val == null || !Object.op_Implicit((Object)(object)val.transform) || val.props == null)
			{
				return false;
			}
			BloodKind kind;
			bool flag = NpcBlood.Resolve(puppetMaster, val, attack.collider, out kind);
			BloodKind kind2 = bloodKind ?? kind;
			if (!health.isOrganic && !hasBloodSurface && !flag)
			{
				return false;
			}
			int instanceID = ((Object)puppetMaster).GetInstanceID();
			if (!_actors.TryGetValue(instanceID, out Actor value))
			{
				if (_actors.Count >= Settings.MaxNpcs.Value)
				{
					Remove(_actors.MinBy<KeyValuePair<int, Actor>, float>((KeyValuePair<int, Actor> pair) => pair.Value.Touched).Key, restore: true);
				}
				value = new Actor
				{
					Puppet = puppetMaster
				};
				_actors.Add(instanceID, value);
			}
			value.Touched = Time.time;
			Vector3 val2 = attack.origin;
			if (!Finite(val2) || Vector3.Distance(val2, val.transform.position) > 1f)
			{
				val2 = val.transform.position;
			}
			if (Object.op_Implicit((Object)(object)attack.collider) && ((Component)attack.collider).transform.IsChildOf(((Component)puppetMaster).transform))
			{
				val2 = attack.collider.ClosestPoint(val2);
			}
			Vector3 val3;
			if (!remote)
			{
				if (value.LastFrame != Time.frameCount)
				{
					value.Contacts.Clear();
					value.LastFrame = Time.frameCount;
				}
				if (value.Contacts.TryGetValue(index, out var value2))
				{
					val3 = val2 - value2;
					if (((Vector3)(ref val3)).sqrMagnitude < 4E-06f)
					{
						return true;
					}
				}
				value.Contacts[index] = val2;
			}
			HitCount++;
			int seed2 = seed ?? Random.Shared.Next();
			Vector3 val4;
			if (Finite(attack.direction))
			{
				val3 = attack.direction;
				if (((Vector3)(ref val3)).sqrMagnitude > 0.001f)
				{
					val3 = attack.direction;
					val4 = ((Vector3)(ref val3)).normalized;
					goto IL_02d3;
				}
			}
			val4 = -val.transform.forward;
			goto IL_02d3;
			IL_0492:
			FractureImpact fractureImpact = FractureImpact.Other;
			goto IL_0495;
			IL_0310:
			Vector3 val5;
			Vector3 normal = (Vector3)val5;
			bool flag2 = (int)attack.attackType != 8 && (int)attack.attackType != 64;
			Vector3 val7;
			Vector3? val6 = (remote ? exitPoint : (((int)attack.attackType == 1) ? HitAnatomy.NpcExit(val, val2, val7) : ((Vector3?)null)));
			Organ organ2 = organ ?? HitAnatomy.Npc(puppetMaster, val, val2, (Vector3)(((??)val6) ?? val2));
			LastOrgan = organ2;
			if (val6.HasValue && flag2)
			{
				ExitHits++;
			}
			if (flag2 && Settings.Blood.Value)
			{
				_blood.WoundSpray(val2, val6, val7, normal, attack.damage, instanceID, seed2, kind2, organ2);
				AddWound(value, val.transform, val2, kind2, organ2, val6);
			}
			if (!remote && NetworkEffects.CanControl(puppetMaster) && Settings.Breaks.Value && ((int)val.props.group == 3 || (int)val.props.group == 5 || (int)val.props.group == 4 || (int)val.props.group == 6))
			{
				AttackType attackType = attack.attackType;
				if ((int)attackType <= 2)
				{
					if ((int)attackType != 1)
					{
						if ((int)attackType != 2)
						{
							goto IL_0492;
						}
						fractureImpact = FractureImpact.Blunt;
					}
					else
					{
						fractureImpact = FractureImpact.Piercing;
					}
				}
				else if ((int)attackType != 16)
				{
					if ((int)attackType != 32)
					{
						goto IL_0492;
					}
					fractureImpact = FractureImpact.Stabbing;
				}
				else
				{
					fractureImpact = FractureImpact.Slicing;
				}
				goto IL_0495;
			}
			goto IL_04f2;
			IL_0495:
			FractureImpact impact = fractureImpact;
			value.Damage.TryGetValue(index, out var value3);
			value3 = FractureRules.Accumulate(value3, attack.damage, impact);
			value.Damage[index] = value3;
			if (value3 >= Settings.BreakThreshold.Value && !value.Fractures.ContainsKey(index))
			{
				Break(value, val, index, val2);
			}
			goto IL_04f2;
			IL_02d3:
			val7 = val4;
			if (Finite(attack.normal))
			{
				val3 = attack.normal;
				if (((Vector3)(ref val3)).sqrMagnitude > 0.001f)
				{
					val3 = attack.normal;
					val5 = ((Vector3)(ref val3)).normalized;
					goto IL_0310;
				}
			}
			val5 = -val7;
			goto IL_0310;
			IL_04f2:
			if (!remote && flag2)
			{
				NetworkEffects.Hit(puppetMaster, index, val2, val7, normal, attack.damage, (int)attack.attackType, seed2, kind2, organ2, val6);
			}
			return true;
		}

		private static bool Finite(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (float.IsFinite(v.x) && float.IsFinite(v.y))
			{
				return float.IsFinite(v.z);
			}
			return false;
		}

		private static void AddWound(Actor actor, Transform anchor, Vector3 point, BloodKind kind, Organ organ, Vector3? exit)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			Wound wound = actor.Wounds.Find((Wound w) => (Object)(object)w.Anchor == (Object)(object)anchor);
			if (wound == null)
			{
				if (actor.Wounds.Count >= 4)
				{
					actor.Wounds.RemoveAt(0);
				}
				wound = new Wound
				{
					Anchor = anchor
				};
				actor.Wounds.Add(wound);
			}
			if (!(wound.Expires > Time.time) || !(HitBleeding.Profile(wound.Organ).Flow > HitBleeding.Profile(organ).Flow))
			{
				wound.Organ = organ;
				wound.LocalPoint = anchor.InverseTransformPoint(point);
				wound.Started = Time.time;
				wound.Kind = kind;
				wound.Expires = Time.time + HitBleeding.Duration(wound.Organ, Settings.BleedSeconds.Value);
				wound.NextDrip = Time.time + HitBleeding.Interval(wound.Organ, Random.Range(0.05f, 0.2f), 1f);
				wound.HasExit = exit.HasValue;
				if (exit.HasValue)
				{
					wound.ExitPoint = anchor.InverseTransformPoint(exit.Value);
				}
				wound.HasContact = (wound.ExitContact = false);
			}
		}

		private void Break(Actor actor, Muscle muscle, int index, Vector3 point)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Fracture value = new Fracture
			{
				Muscle = muscle
			};
			actor.Fractures.Add(index, value);
			BrokenMuscles.Add(((Il2CppObjectBase)muscle).Pointer);
			FractureCount++;
			_audio.Crack(point);
			NetworkEffects.Crack(actor.Puppet, point);
		}

		internal void Update()
		{
			//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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: 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_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			_remove.Clear();
			foreach (KeyValuePair<int, Actor> actor in _actors)
			{
				Actor value = actor.Value;
				if (!Object.op_Implicit((Object)(object)value.Puppet) || !((Component)value.Puppet).gameObject.activeInHierarchy || value.Puppet.hasBeenDespawned)
				{
					_remove.Add(actor.Key);
					continue;
				}
				if (!Settings.Breaks.Value || !NetworkEffects.CanControl(value.Puppet))
				{
					foreach (Fracture value2 in value.Fractures.Values)
					{
						BrokenMuscles.Remove(((Il2CppObjectBase)value2.Muscle).Pointer);
					}
					value.Fractures.Clear();
					value.Damage.Clear();
				}
				for (int num = value.Wounds.Count - 1; num >= 0; num--)
				{
					Wound wound = value.Wounds[num];
					if (!Object.op_Implicit((Object)(object)wound.Anchor) || Time.time >= wound.Expires || !Settings.Blood.Value)
					{
						value.Wounds.RemoveAt(num);
					}
					else
					{
						Vector3 point = wound.Anchor.TransformPoint(wound.LocalPoint);
						float remaining = Mathf.Clamp01((wound.Expires - Time.time) / (wound.Expires - wound.Started));
						if (Time.time >= wound.NextDrip)
						{
							_blood.Drip(point, actor.Key, wound.Organ == Organ.Extremity, wound.Kind);
							if (wound.HasExit)
							{
								_blood.Drip(wound.Anchor.TransformPoint(wound.ExitPoint), actor.Key, wound.Organ == Organ.Extremity, wound.Kind);
							}
							wound.NextDrip = Time.time + HitBleeding.Interval(wound.Organ, Random.Range(0.2f, 0.65f), remaining);
						}
						if (Settings.Smears.Value && Time.time >= wound.NextSmear)
						{
							wound.NextSmear = Time.time + 0.065f;
							_blood.Smear(point, actor.Key, remaining, ref wound.Previous, ref wound.HasContact, wound.Kind);
							if (wound.HasExit)
							{
								_blood.Smear(wound.Anchor.TransformPoint(wound.ExitPoint), actor.Key, remaining, ref wound.ExitPrevious, ref wound.ExitContact, wound.Kind);
							}
						}
						else if (!Settings.Smears.Value)
						{
							wound.HasContact = (wound.ExitContact = false);
						}
					}
				}
				if (value.Wounds.Count == 0 && value.Fractures.Count == 0 && Time.time - value.Touched > 45f)
				{
					_remove.Add(actor.Key);
				}
			}
			foreach (int item in _remove)
			{
				Remove(item, restore: true);
			}
		}

		internal void Reset(PuppetMaster puppet)
		{
			NpcBlood.Reset(puppet);
			if (Object.op_Implicit((Object)(object)puppet))
			{
				Remove(((Object)puppet).GetInstanceID(), restore: true);
			}
		}

		internal void RestoreFractures()
		{
			foreach (Actor value in _actors.Values)
			{
				value.Fractures.Clear();
				value.Damage.Clear();
			}
			BrokenMuscles.Clear();
		}

		private void Remove(int id, bool restore)
		{
			if (!_actors.Remove(id, out Actor value))
			{
				return;
			}
			foreach (Fracture value2 in value.Fractures.Values)
			{
				BrokenMuscles.Remove(((Il2CppObjectBase)value2.Muscle).Pointer);
			}
		}

		internal void Clear()
		{
			int[] array = _actors.Keys.ToArray();
			foreach (int id in array)
			{
				Remove(id, restore: true);
			}
			BrokenMuscles.Clear();
			NpcBlo

Mods/CrimsonFusion.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using Crimson;
using Crimson.Core;
using CrimsonFusion;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.PuppetMasta;
using LabFusion.Entities;
using LabFusion.Marrow.Extenders;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using LabFusion.Scene;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(FusionBridge), "Crimson Fusion", "1.1.8", "Crimson Mod Project", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "Crimson", "LabFusion" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("CrimsonFusion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.8.0")]
[assembly: AssemblyInformationalVersion("1.1.8")]
[assembly: AssemblyProduct("CrimsonFusion")]
[assembly: AssemblyTitle("CrimsonFusion")]
[assembly: AssemblyVersion("1.1.8.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace CrimsonFusion
{
	public sealed class FusionBridge : MelonMod, ICrimsonNetwork
	{
		internal static FusionBridge? Instance;

		private readonly Queue<(byte Sender, EffectPacket Packet)> _incoming = new Queue<(byte, EffectPacket)>();

		private readonly Dictionary<byte, PeerWindow> _peers = new Dictionary<byte, PeerWindow>();

		private readonly object _gate = new object();

		private bool _running;

		private ulong _epoch;

		private ulong _level;

		private uint _sequence;

		private float _nextHello;

		private float _tokenAt;

		private float _tokens = 90f;

		private int _sent;

		private int _received;

		private int _applied;

		private int _rejected;

		private int _overflow;

		bool ICrimsonNetwork.Active => _running;

		string ICrimsonNetwork.Status => $"{(_running ? "connected" : "waiting for Fusion/level")}; sent={_sent}, received={_received}, applied={_applied}, rejected={_rejected}, overflow={_overflow}";

		public override void OnInitializeMelon()
		{
			Instance = this;
			ModuleMessageManager.RegisterHandler<CrimsonEffectMessage>();
			NetworkEffects.Transport = (ICrimsonNetwork)(object)this;
			((MelonBase)this).LoggerInstance.Msg("Crimson Fusion 1.1.8: NPC/player blood sharing enabled. Each participant needs both Crimson DLLs.");
		}

		public override void OnUpdate()
		{
			//IL_0161: 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_00ec: 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)
			int num;
			object obj;
			if (NetworkInfo.HasServer)
			{
				CrimsonMod instance = CrimsonMod.Instance;
				if (instance != null && instance.Ready && Settings.Enabled.Value)
				{
					num = (Settings.Fusion.Value ? 1 : 0);
					if (num == 0)
					{
						goto IL_0036;
					}
					obj = NetworkSceneManager.GetLevelBarcode(PlayerIDManager.LocalID);
					goto IL_0047;
				}
			}
			num = 0;
			goto IL_0036;
			IL_0036:
			obj = "";
			goto IL_0047;
			IL_0047:
			string text = (string)obj;
			if (num == 0 || string.IsNullOrEmpty(text))
			{
				StopSession();
				return;
			}
			ulong num2 = EffectPacket.LevelHash(text);
			if (!_running || _level != num2)
			{
				StopSession();
				_running = true;
				_level = num2;
				_epoch = BitConverter.ToUInt64(RandomNumberGenerator.GetBytes(8));
				if (_epoch == 0L)
				{
					_epoch = 1uL;
				}
				_nextHello = 0f;
				_sequence = 0u;
				_tokens = 90f;
				_tokenAt = Time.unscaledTime;
			}
			if (Time.unscaledTime >= _nextHello)
			{
				SendPacket(new EffectPacket
				{
					Kind = (EffectKind)0,
					Entity = ushort.MaxValue
				});
				_nextHello = Time.unscaledTime + 2f;
			}
			for (int i = 0; i < 32; i++)
			{
				(byte, EffectPacket) tuple;
				lock (_gate)
				{
					if (_incoming.Count == 0)
					{
						break;
					}
					tuple = _incoming.Dequeue();
				}
				try
				{
					Receive(tuple.Item1, tuple.Item2);
				}
				catch (Exception ex)
				{
					_rejected++;
					CrimsonMod.Report("Fusion receive", ex);
				}
			}
		}

		private void StopSession()
		{
			if (!_running)
			{
				lock (_gate)
				{
					_incoming.Clear();
					return;
				}
			}
			_running = false;
			_peers.Clear();
			lock (_gate)
			{
				_incoming.Clear();
			}
			CrimsonMod instance = CrimsonMod.Instance;
			if (instance != null)
			{
				instance.Npcs.RestoreFractures();
			}
		}

		public override void OnDeinitializeMelon()
		{
			StopSession();
			if ((object)NetworkEffects.Transport == this)
			{
				NetworkEffects.Transport = null;
			}
			Instance = null;
		}

		internal void Queue(byte sender, EffectPacket packet)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			lock (_gate)
			{
				if (_incoming.Count >= 256)
				{
					_overflow++;
				}
				else
				{
					_incoming.Enqueue((sender, packet));
				}
			}
		}

		bool ICrimsonNetwork.CanControl(PuppetMaster puppet)
		{
			NetworkEntity val = default(NetworkEntity);
			if (!NetworkInfo.HasServer || !PuppetMasterExtender.Cache.TryGet(puppet, ref val))
			{
				return true;
			}
			if (!val.IsOwner)
			{
				if (!val.HasOwner)
				{
					return NetworkInfo.IsHost;
				}
				return false;
			}
			return true;
		}

		void ICrimsonNetwork.Send(EffectPacket packet, PuppetMaster? puppet)
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Invalid comparison between Unknown and I4
			//IL_0127: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_006b: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00e7: 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_00ff: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (!_running)
			{
				return;
			}
			packet.Entity = ushort.MaxValue;
			NetworkEntity val = default(NetworkEntity);
			if (Object.op_Implicit((Object)(object)puppet) && PuppetMasterExtender.Cache.TryGet(puppet, ref val))
			{
				if (!val.IsOwner && (val.HasOwner || !NetworkInfo.IsHost))
				{
					return;
				}
				packet.Entity = val.ID;
				if ((int)packet.Kind == 1)
				{
					if (puppet.muscles == null || packet.Muscle >= ((Il2CppArrayBase<Muscle>)(object)puppet.muscles).Length)
					{
						return;
					}
					Transform transform = ((Il2CppArrayBase<Muscle>)(object)puppet.muscles)[(int)packet.Muscle].transform;
					packet.Point = NetworkEffects.N(transform.InverseTransformPoint(NetworkEffects.U(packet.Point)));
					if (((EffectPacket)(ref packet)).HasExit)
					{
						packet.ExitPoint = NetworkEffects.N(transform.InverseTransformPoint(NetworkEffects.U(packet.ExitPoint)));
					}
					packet.Direction = NetworkEffects.N(transform.InverseTransformDirection(NetworkEffects.U(packet.Direction)));
					packet.Normal = NetworkEffects.N(transform.InverseTransformDirection(NetworkEffects.U(packet.Normal)));
				}
			}
			else if ((int)packet.Kind == 1)
			{
				packet.Kind = (EffectKind)2;
			}
			SendPacket(packet);
		}

		void ICrimsonNetwork.SendPlayer(EffectPacket packet, RigManager rig)
		{
			//IL_0014: 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_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_0081: 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_008c: 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_00b9: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkPlayer val = default(NetworkPlayer);
			if (!_running || !NetworkPlayerManager.TryGetPlayer(rig, ref val))
			{
				return;
			}
			Transform val2 = PlayerBleeding.Bone(rig, (HumanBodyBones)packet.Muscle);
			if (Object.op_Implicit((Object)(object)val2))
			{
				packet.Entity = val.PlayerID.SmallID;
				packet.Point = NetworkEffects.N(val2.InverseTransformPoint(NetworkEffects.U(packet.Point)));
				if (((EffectPacket)(ref packet)).HasExit)
				{
					packet.ExitPoint = NetworkEffects.N(val2.InverseTransformPoint(NetworkEffects.U(packet.ExitPoint)));
				}
				packet.Direction = NetworkEffects.N(val2.InverseTransformDirection(NetworkEffects.U(packet.Direction)));
				packet.Normal = NetworkEffects.N(val2.InverseTransformDirection(NetworkEffects.U(packet.Normal)));
				SendPacket(packet);
			}
		}

		private void SendPacket(EffectPacket packet)
		{
			//IL_003c: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			_tokens = Math.Min(90f, _tokens + Math.Max(0f, unscaledTime - _tokenAt) * 60f);
			_tokenAt = unscaledTime;
			if ((int)packet.Kind != 0)
			{
				if (_tokens < 1f)
				{
					_overflow++;
					return;
				}
				_tokens -= 1f;
			}
			packet.Epoch = _epoch;
			packet.Level = _level;
			packet.Sequence = ++_sequence;
			if (!((EffectPacket)(ref packet)).Valid())
			{
				_rejected++;
				return;
			}
			MessageRelay.RelayModule<CrimsonEffectMessage, EffectData>(new EffectData
			{
				Bytes = ((EffectPacket)(ref packet)).Encode()
			}, CommonMessageRoutes.ReliableToOtherClients);
			_sent++;
		}

		private void Receive(byte sender, EffectPacket p)
		{
			//IL_0016: 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_00b5: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Invalid comparison between Unknown and I4
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0146: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0181: 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_0190: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			_received++;
			if (sender == PlayerIDManager.LocalSmallID || p.Level != _level)
			{
				_rejected++;
				return;
			}
			PlayerID playerID = PlayerIDManager.GetPlayerID(sender);
			if (playerID == null || !NetworkSceneManager.InCurrentLevel(playerID))
			{
				_rejected++;
				return;
			}
			if (!_peers.TryGetValue(sender, out PeerWindow value))
			{
				if (_peers.Count >= 254)
				{
					_rejected++;
					return;
				}
				value = new PeerWindow();
				_peers.Add(sender, value);
			}
			if (!value.Accept(p, Time.unscaledTimeAsDouble))
			{
				_rejected++;
			}
			else
			{
				if ((int)p.Kind == 0)
				{
					return;
				}
				if ((int)p.Kind == 5)
				{
					NetworkPlayer val = default(NetworkPlayer);
					if (!NetworkPlayerManager.TryGetPlayer((byte)p.Entity, ref val) || !val.HasRig || !NetworkSceneManager.InCurrentLevel(val.PlayerID))
					{
						_rejected++;
						return;
					}
					RigManager rigManager = val.RigRefs.RigManager;
					Transform val2 = PlayerBleeding.Bone(rigManager, (HumanBodyBones)p.Muscle);
					if (!Object.op_Implicit((Object)(object)val2))
					{
						_rejected++;
						return;
					}
					CrimsonMod.Instance.Players.Apply(rigManager, (HumanBodyBones)p.Muscle, val2.TransformPoint(NetworkEffects.U(p.Point)), val2.TransformDirection(NetworkEffects.U(p.Direction)), val2.TransformDirection(NetworkEffects.U(p.Normal)), p.Amount, true, p.Seed, (int)sender, (AttackType)p.AttackType, (Organ?)((EffectPacket)(ref p)).Organ, ((EffectPacket)(ref p)).HasExit ? new Vector3?(val2.TransformPoint(NetworkEffects.U(p.ExitPoint))) : ((Vector3?)null));
					_applied++;
					return;
				}
				PuppetMaster val3 = null;
				if (p.Entity != ushort.MaxValue)
				{
					NetworkEntityReference val4 = new NetworkEntityReference(p.Entity);
					NetworkEntity val5 = default(NetworkEntity);
					if (!((NetworkEntityReference)(ref val4)).TryGetEntity(ref val5) || val5.IsDestroyed)
					{
						_rejected++;
						return;
					}
					if ((val5.HasOwner ? val5.OwnerID.SmallID : 0) != sender)
					{
						_rejected++;
						return;
					}
					val3 = ((EntityComponentExtender<PuppetMaster>)(object)val5.GetExtender<PuppetMasterExtender>())?.Component;
					if (!Object.op_Implicit((Object)(object)val3))
					{
						_rejected++;
						return;
					}
				}
				NetworkEffects.Apply(p, val3);
				_applied++;
			}
		}
	}
	public sealed class EffectData : INetSerializable
	{
		public byte[] Bytes = new byte[92];

		public int? GetSize()
		{
			return 92;
		}

		public void Serialize(INetSerializer serializer)
		{
			for (int i = 0; i < 92; i++)
			{
				serializer.SerializeValue(ref Bytes[i]);
			}
		}
	}
	public sealed class CrimsonEffectMessage : ModuleMessageHandler
	{
		protected override bool OnPreRelayMessage(ReceivedMessage received)
		{
			EffectPacket val = default(EffectPacket);
			return EffectPacket.TryDecode((ReadOnlySpan<byte>)((ReceivedMessage)(ref received)).Bytes, ref val);
		}

		protected override void OnHandleMessage(ReceivedMessage received)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			EffectPacket packet = default(EffectPacket);
			if (((ReceivedMessage)(ref received)).Sender.HasValue && EffectPacket.TryDecode((ReadOnlySpan<byte>)((ReceivedMessage)(ref received)).Bytes, ref packet))
			{
				FusionBridge.Instance?.Queue(((ReceivedMessage)(ref received)).Sender.Value, packet);
			}
		}
	}
}