Decompiled source of SimpleBlood v1.0.0

Mods/SimpleBlood.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.PuppetMasta;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SimpleBlood;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "SimpleBlood", "1.0.0", "kamonkus", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SimpleBlood
{
	internal static class BloodManager
	{
		private sealed class Splat
		{
			public GameObject Go;

			public Transform Tr;

			public SpriteRenderer Sr;

			public float Born;

			public float Alpha;

			public bool Active;

			public bool Pinned;

			public bool Gloss;

			public float GlossAlpha;

			public int Version;

			public bool HasAnchor;

			public Transform Anchor;

			public Vector3 AnchorLocal;
		}

		private struct RootInfo
		{
			public bool Big;

			public bool Has;

			public Bounds B;
		}

		private sealed class Droplet
		{
			public GameObject Go;

			public Transform Tr;

			public SpriteRenderer Sr;

			public Vector3 Vel;

			public float Age;

			public float Life;

			public float Size;

			public bool Mist;

			public bool Active;
		}

		private sealed class Wound
		{
			public Transform Parent;

			public Vector3 LocalPos;

			public Vector3 LocalDir;

			public PuppetMaster Pm;

			public int PmId;

			public float Start;

			public float Duration;

			public float Intensity;

			public float Acc;
		}

		private sealed class FloorPool
		{
			public Splat S;

			public int Version;

			public Splat G;

			public int GVersion;

			public Vector3 Pos;

			public Vector3 Normal;

			public float Amount;

			public float Size;

			public float Target;
		}

		private sealed class Runner
		{
			public Splat S;

			public int Version;

			public Splat Head;

			public int HeadVersion;

			public Vector3 Top;

			public Vector3 Down;

			public Vector3 Normal;

			public float Len;

			public float MaxLen;

			public float Speed;

			public float Width;
		}

		private sealed class Corpse
		{
			public PuppetMaster Pm;

			public int Id;

			public float Blood;

			public bool BrainDead;

			public bool WasDead;

			public bool Cached;

			public bool HasLast;

			public bool HasTrailStart;

			public float NextCheck;

			public float LastCheck;

			public float TrailLeft;

			public Vector3 Last;

			public Vector3 LastTrailGround;

			public readonly List<Rigidbody> Bodies = new List<Rigidbody>();
		}

		private const int MaxDroplets = 500;

		private const int MaxWounds = 32;

		private const int MaxPools = 50;

		private const int MaxRunners = 40;

		private static bool _inited;

		private static Transform _root;

		private static int _mask;

		private static Sprite[] _splatSprites;

		private static Sprite[] _dropSprites;

		private static Sprite[] _puddleSprites;

		private static Sprite _smearSprite;

		private static Sprite _dotSprite;

		private static Sprite _runSprite;

		private static Sprite _glossSprite;

		private static readonly List<Splat> _splats = new List<Splat>();

		private static readonly List<Droplet> _droplets = new List<Droplet>();

		private static readonly List<Wound> _wounds = new List<Wound>();

		private static readonly List<Corpse> _corpses = new List<Corpse>();

		private static readonly List<FloorPool> _pools = new List<FloorPool>();

		private static readonly List<Runner> _runners = new List<Runner>();

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

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

		private static readonly Dictionary<int, Renderer> _rendererCache = new Dictionary<int, Renderer>();

		private static readonly Dictionary<int, RootInfo> _rootCache = new Dictionary<int, RootInfo>();

		private static int _floorLogs;

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

		private static int _ring;

		private static int _colorCursor;

		private static int _order;

		private static int _hitsThisFrame;

		private static int _activeDroplets;

		private static int _hitLogs;

		private static float _nextDebugLog;

		private static float _nextTickError;

		public static void EnsureInit()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (_inited)
			{
				return;
			}
			_inited = true;
			GameObject val = new GameObject("SimpleBlood_Root");
			Object.DontDestroyOnLoad((Object)val);
			_root = val.transform;
			string[] array = new string[20]
			{
				"transparentfx", "ignoreraycast", "water", "ui", "player", "nocollide", "enemycolliders", "socket", "plug", "playerandnpc",
				"feetonly", "feet", "nofootball", "entitytracker", "beingtracker", "observertracker", "entitytrigger", "beingtrigger", "observertrigger", "background"
			};
			int num = 0;
			string text = "";
			for (int i = 0; i < 32; i++)
			{
				string text2 = LayerMask.LayerToName(i);
				if (!string.IsNullOrEmpty(text2))
				{
					text = text + i + "=" + text2 + " ";
					string value = text2.Replace(" ", "").Replace("_", "").ToLowerInvariant();
					if (Array.IndexOf(array, value) >= 0)
					{
						num |= 1 << i;
					}
				}
			}
			_mask = ~num;
			MelonLogger.Msg("[SimpleBlood] Layers: " + text + "| blocked mask=" + num);
			GenerateTextures();
			MelonLogger.Msg("[SimpleBlood] Textures generated.");
		}

		public static void Tick()
		{
			if (!_inited)
			{
				return;
			}
			float time = Time.time;
			float deltaTime = Time.deltaTime;
			_hitsThisFrame = 0;
			try
			{
				TickDroplets(deltaTime);
			}
			catch (Exception e)
			{
				LogTickError("droplets", e);
			}
			try
			{
				TickWounds(time, deltaTime);
			}
			catch (Exception e2)
			{
				LogTickError("wounds", e2);
			}
			try
			{
				TickCorpses(time);
			}
			catch (Exception e3)
			{
				LogTickError("corpses", e3);
			}
			try
			{
				TickPools(deltaTime);
			}
			catch (Exception e4)
			{
				LogTickError("pools", e4);
			}
			try
			{
				TickRunners(deltaTime);
			}
			catch (Exception e5)
			{
				LogTickError("runners", e5);
			}
			try
			{
				UpdateColors(time);
			}
			catch (Exception e6)
			{
				LogTickError("colors", e6);
			}
		}

		private static void LogTickError(string stage, Exception e)
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!(realtimeSinceStartup < _nextTickError))
			{
				_nextTickError = realtimeSinceStartup + 5f;
				MelonLogger.Error("[SimpleBlood] error in " + stage + ": " + e);
			}
		}

		public static void ClearAll()
		{
			try
			{
				for (int i = 0; i < _splats.Count; i++)
				{
					if (_splats[i].Active)
					{
						Deactivate(_splats[i]);
					}
				}
				for (int j = 0; j < _droplets.Count; j++)
				{
					if (_droplets[j].Active)
					{
						KillDroplet(_droplets[j]);
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[SimpleBlood] ClearAll: " + ex.Message);
			}
			_wounds.Clear();
			_corpses.Clear();
			_pools.Clear();
			_runners.Clear();
			_pending.Clear();
		}

		private static bool CastWorld(Vector3 origin, Vector3 dir, float dist, out RaycastHit result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0040: 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_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)
			result = default(RaycastHit);
			Vector3 val = origin;
			float num = dist;
			RaycastHit val2 = default(RaycastHit);
			for (int i = 0; i < 3; i++)
			{
				if (!(num > 0.0001f))
				{
					break;
				}
				if (!Physics.Raycast(val, dir, ref val2, num, _mask, (QueryTriggerInteraction)1))
				{
					return false;
				}
				if (IsIgnoredCollider(((RaycastHit)(ref val2)).collider))
				{
					float num2 = ((RaycastHit)(ref val2)).distance + 0.01f;
					val += dir * num2;
					num -= num2;
					continue;
				}
				result = val2;
				return true;
			}
			return false;
		}

		private static bool IsPlayerCollider(Collider c)
		{
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager == (Object)null)
				{
					return false;
				}
				return ((Component)c).transform.IsChildOf(((Component)rigManager).transform);
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static bool IsIgnoredCollider(Collider c)
		{
			if (IsPlayerCollider(c))
			{
				return true;
			}
			int instanceID = ((Object)c).GetInstanceID();
			if (_ignoredCache.TryGetValue(instanceID, out var value))
			{
				return value;
			}
			value = (Object)(object)((Component)c).GetComponentInParent<PuppetMaster>() != (Object)null;
			if (!value)
			{
				Transform root = ((Component)c).transform.root;
				if ((Object)(object)root != (Object)null && root.childCount <= 40)
				{
					value = (Object)(object)((Component)root).GetComponentInChildren<PuppetMaster>() != (Object)null;
				}
			}
			if (_ignoredCache.Count > 4000)
			{
				_ignoredCache.Clear();
			}
			_ignoredCache[instanceID] = value;
			return value;
		}

		public static void OnBrainDie(AIBrain brain)
		{
			SetBrainDead(brain, dead: true);
		}

		public static void OnBrainResurrected(AIBrain brain)
		{
			SetBrainDead(brain, dead: false);
		}

		private static void SetBrainDead(AIBrain brain, bool dead)
		{
			try
			{
				if ((Object)(object)brain == (Object)null)
				{
					return;
				}
				PuppetMaster puppetMaster = brain.puppetMaster;
				if ((Object)(object)puppetMaster == (Object)null)
				{
					return;
				}
				int instanceID = ((Object)puppetMaster).GetInstanceID();
				for (int i = 0; i < _corpses.Count; i++)
				{
					if (_corpses[i].Id == instanceID)
					{
						_corpses[i].BrainDead = dead;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		public unsafe static void OnNpcHit(SubBehaviourHealth sub, Attack attack, float result)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_0156: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: 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_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.Enabled.Value || _hitsThisFrame >= 24)
			{
				return;
			}
			Collider collider = attack.collider;
			if ((Object)(object)collider == (Object)null)
			{
				return;
			}
			float num = TypeScale(attack.attackType);
			if (num <= 0f)
			{
				return;
			}
			float damage = attack.damage;
			if (damage <= 0f && result <= 0f)
			{
				return;
			}
			bool isOrganic = sub.isOrganic;
			if (Settings.OrganicOnly.Value && !isOrganic)
			{
				return;
			}
			PuppetMaster componentInParent = ((Component)collider).GetComponentInParent<PuppetMaster>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			string text = AncestorNames(((Component)componentInParent).transform);
			if (_seenNames.Count < 40 && _seenNames.Add(text))
			{
				MelonLogger.Msg("[SimpleBlood] NPC hit: " + text + " (organic=" + isOrganic + ")");
			}
			if (Settings.Mode.Value == 1)
			{
				string value = Settings.NameFilter.Value;
				if (!string.IsNullOrWhiteSpace(value) && text.IndexOf(value.Trim(), StringComparison.OrdinalIgnoreCase) < 0)
				{
					return;
				}
			}
			EnsureInit();
			_hitsThisFrame++;
			Vector3 val = attack.direction;
			Bounds bounds;
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				bounds = collider.bounds;
				val = ((Bounds)(ref bounds)).center - attack.origin;
			}
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				val = Vector3.forward;
			}
			((Vector3)(ref val)).Normalize();
			Ray val2 = default(Ray);
			((Ray)(ref val2))..ctor(attack.origin - val * 0.35f, val);
			RaycastHit val3 = default(RaycastHit);
			Vector3 val4;
			Vector3 val5;
			if (collider.Raycast(val2, ref val3, 250f))
			{
				val4 = ((RaycastHit)(ref val3)).point;
				val5 = ((RaycastHit)(ref val3)).normal;
			}
			else
			{
				val4 = collider.ClosestPoint(attack.origin);
				Vector3 val6 = val4;
				bounds = collider.bounds;
				val5 = val6 - ((Bounds)(ref bounds)).center;
				if (((Vector3)(ref val5)).sqrMagnitude < 1E-06f)
				{
					val5 = -val;
				}
				((Vector3)(ref val5)).Normalize();
			}
			if (Vector3.Dot(val5, val) > 0f)
			{
				val5 = -val5;
			}
			Vector3 val7;
			if (Settings.Debug.Value && Time.time > _nextDebugLog)
			{
				_nextDebugLog = Time.time + 0.15f;
				string[] obj = new string[10]
				{
					"[SimpleBlood] hit type=",
					((object)attack.attackType/*cast due to .constrained prefix*/).ToString(),
					" dmg=",
					damage.ToString(),
					" result=",
					result.ToString(),
					" point=",
					null,
					null,
					null
				};
				val7 = val4;
				obj[7] = ((object)(*(Vector3*)(&val7))/*cast due to .constrained prefix*/).ToString();
				obj[8] = " dir=";
				val7 = val;
				obj[9] = ((object)(*(Vector3*)(&val7))/*cast due to .constrained prefix*/).ToString();
				MelonLogger.Msg(string.Concat(obj));
			}
			float num2 = num * Mathf.Clamp(0.75f + Mathf.Sqrt(Mathf.Max(0f, damage)) * 0.15f, 0.75f, 1.6f);
			int num3 = Mathf.RoundToInt((float)Settings.Droplets.Value * num2);
			int num4 = Mathf.RoundToInt((float)num3 * Settings.BackSpray.Value);
			int num5 = num3 - num4;
			float value2 = Settings.SprayPower.Value;
			float value3 = Settings.SprayAngle.Value;
			val7 = -val * 0.6f + val5 * 0.4f;
			Vector3 normalized = ((Vector3)(ref val7)).normalized;
			for (int i = 0; i < num5; i++)
			{
				Vector3 vel = RandomInCone(val, value3) * SpraySpeed(value2);
				SpawnDroplet(val4 + val * 0.12f, vel, DropletDiameter(), mist: false, 2.5f);
			}
			for (int j = 0; j < num4; j++)
			{
				Vector3 vel2 = RandomInCone(normalized, value3 * 1.5f) * (SpraySpeed(value2) * 0.55f);
				SpawnDroplet(val4 + val5 * 0.02f, vel2, DropletDiameter(), mist: false, 2f);
			}
			if (Settings.Mist.Value)
			{
				int num6 = Mathf.RoundToInt(16f * num2);
				Vector3 axis = Vector3.Slerp(normalized, val, 0.4f);
				for (int k = 0; k < num6; k++)
				{
					Vector3 vel3 = RandomInCone(axis, 55f) * Random.Range(1f, 5f);
					SpawnDroplet(val4 + val5 * 0.02f, vel3, Random.Range(0.006f, 0.014f), mist: true, Random.Range(0.2f, 0.45f));
				}
			}
			AddWound(((Component)collider).transform, val4, val5, componentInParent, num2);
			AddBlood(componentInParent, 14f * num2);
		}

		private static float TypeScale(AttackType t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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
			if ((int)t == 8)
			{
				return 0f;
			}
			if ((int)t == 2)
			{
				return 0.35f;
			}
			if ((int)t == 64)
			{
				return 0.5f;
			}
			return 1f;
		}

		private static string AncestorNames(Transform t)
		{
			string text = "";
			int num = 0;
			while ((Object)(object)t != (Object)null && num < 6)
			{
				text = text + ((Object)t).name + "/";
				t = t.parent;
				num++;
			}
			return text;
		}

		private static float SpraySpeed(float power)
		{
			return Mathf.Lerp(2f, 10f, Mathf.Pow(Random.value, 1.6f)) * power;
		}

		private static float DropletDiameter()
		{
			return ((Random.value < 0.14f) ? Random.Range(0.03f, 0.055f) : Random.Range(0.012f, 0.03f)) * Settings.DropletSize.Value;
		}

		private static Vector3 RandomInCone(Vector3 axis, float angleDeg)
		{
			//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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			float num = angleDeg * ((float)Math.PI / 180f);
			float num2 = Mathf.Lerp(1f, Mathf.Cos(num), Random.value);
			float num3 = Random.value * 2f * (float)Math.PI;
			float num4 = Mathf.Sqrt(Mathf.Max(0f, 1f - num2 * num2));
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(num4 * Mathf.Cos(num3), num4 * Mathf.Sin(num3), num2);
			return Quaternion.FromToRotation(Vector3.forward, axis) * val;
		}

		private static void AddWound(Transform parent, Vector3 point, Vector3 normal, PuppetMaster pm, float scale)
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Bleeding.Value)
			{
				if (_wounds.Count >= 32)
				{
					_wounds.RemoveAt(0);
				}
				Wound wound = new Wound();
				wound.Parent = parent;
				wound.LocalPos = parent.InverseTransformPoint(point);
				wound.LocalDir = parent.InverseTransformDirection(normal);
				wound.Pm = pm;
				wound.PmId = ((Object)pm).GetInstanceID();
				wound.Start = Time.time;
				wound.Duration = Settings.BleedSeconds.Value * Random.Range(0.8f, 1.3f);
				wound.Intensity = Mathf.Clamp(scale, 0.6f, 1.6f);
				_wounds.Add(wound);
			}
		}

		private static Corpse FindCorpse(PuppetMaster pm, bool create)
		{
			int instanceID = ((Object)pm).GetInstanceID();
			for (int i = 0; i < _corpses.Count; i++)
			{
				if (_corpses[i].Id == instanceID)
				{
					return _corpses[i];
				}
			}
			if (!create)
			{
				return null;
			}
			if (_corpses.Count >= 40)
			{
				_corpses.RemoveAt(0);
			}
			Corpse corpse = new Corpse();
			corpse.Pm = pm;
			corpse.Id = instanceID;
			_corpses.Add(corpse);
			return corpse;
		}

		private static void AddBlood(PuppetMaster pm, float amount)
		{
			Corpse corpse = FindCorpse(pm, create: true);
			corpse.Blood = Mathf.Min(120f, corpse.Blood + amount);
		}

		private static Droplet GetDroplet()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			for (int i = 0; i < _droplets.Count; i++)
			{
				if (!_droplets[i].Active)
				{
					return _droplets[i];
				}
			}
			GameObject val = new GameObject("blood_drop");
			val.layer = 2;
			val.transform.SetParent(_root, false);
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			val2.sprite = _dotSprite;
			((Renderer)val2).sortingOrder = 29990;
			val.SetActive(false);
			Droplet droplet = new Droplet();
			droplet.Go = val;
			droplet.Tr = val.transform;
			droplet.Sr = val2;
			_droplets.Add(droplet);
			return droplet;
		}

		private static void SpawnDroplet(Vector3 pos, Vector3 vel, float size, bool mist, float life)
		{
			//IL_001a: 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_0047: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			if (_activeDroplets < 500)
			{
				Droplet droplet = GetDroplet();
				droplet.Active = true;
				droplet.Vel = vel;
				droplet.Age = 0f;
				droplet.Life = life;
				droplet.Size = size;
				droplet.Mist = mist;
				droplet.Tr.position = pos;
				droplet.Tr.localScale = new Vector3(size, size, 1f);
				droplet.Sr.color = BloodColor(0f, mist ? 0.5f : 0.95f);
				droplet.Go.SetActive(true);
				_activeDroplets++;
			}
		}

		private static void KillDroplet(Droplet d)
		{
			if (d.Active)
			{
				d.Active = false;
				d.Go.SetActive(false);
				_activeDroplets--;
			}
		}

		private static void TickDroplets(float dt)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			if (_activeDroplets <= 0 || dt <= 0f)
			{
				return;
			}
			Vector3 gravity = Physics.gravity;
			Quaternion rotation = Quaternion.identity;
			Vector3 forward = Vector3.forward;
			Vector3 up = Vector3.up;
			bool flag = false;
			Transform head = Player.Head;
			if ((Object)(object)head != (Object)null)
			{
				rotation = head.rotation;
				forward = head.forward;
				up = head.up;
				flag = true;
			}
			Color val = BloodColor(0f, 0.55f);
			for (int i = 0; i < _droplets.Count; i++)
			{
				Droplet droplet = _droplets[i];
				if (!droplet.Active)
				{
					continue;
				}
				droplet.Age += dt;
				if (droplet.Age >= droplet.Life)
				{
					KillDroplet(droplet);
					continue;
				}
				Vector3 position = droplet.Tr.position;
				droplet.Vel += gravity * (dt * (droplet.Mist ? 0.3f : 1f));
				Vector3 val2 = droplet.Vel * dt;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (!droplet.Mist && magnitude > 1E-05f && CastWorld(position, val2 / magnitude, magnitude + 0.01f, out var result))
				{
					OnDropletHit(droplet, result, droplet.Vel);
					KillDroplet(droplet);
					continue;
				}
				droplet.Tr.position = position + val2;
				if (flag)
				{
					if (droplet.Mist)
					{
						droplet.Tr.rotation = rotation;
					}
					else
					{
						Vector3 val3 = Vector3.ProjectOnPlane(droplet.Vel, forward);
						if (((Vector3)(ref val3)).sqrMagnitude < 1E-06f)
						{
							val3 = up;
						}
						droplet.Tr.rotation = Quaternion.LookRotation(forward, ((Vector3)(ref val3)).normalized);
						float num = 1f + Mathf.Clamp(((Vector3)(ref droplet.Vel)).magnitude * 0.18f, 0f, 3.5f);
						droplet.Tr.localScale = new Vector3(droplet.Size, droplet.Size * num, 1f);
					}
				}
				if (droplet.Mist)
				{
					Color color = val;
					color.a = (1f - droplet.Age / droplet.Life) * 0.55f;
					droplet.Sr.color = color;
				}
			}
		}

		private static bool SurfaceLooksReal(Collider c, Vector3 point, Vector3 normal)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.ValidateSurfaces.Value)
			{
				return true;
			}
			try
			{
				int instanceID = ((Object)c).GetInstanceID();
				if (!_rendererCache.TryGetValue(instanceID, out var value))
				{
					value = ((Component)c).GetComponentInParent<Renderer>();
					if ((Object)(object)value == (Object)null)
					{
						value = ((Component)c).GetComponentInChildren<Renderer>();
					}
					if (_rendererCache.Count > 4000)
					{
						_rendererCache.Clear();
					}
					_rendererCache[instanceID] = value;
				}
				if ((Object)(object)value != (Object)null)
				{
					Bounds bounds = value.bounds;
					((Bounds)(ref bounds)).Expand(0.15f);
					if (((Bounds)(ref bounds)).Contains(point))
					{
						return true;
					}
				}
				Transform root = ((Component)c).transform.root;
				if ((Object)(object)root == (Object)null)
				{
					return true;
				}
				int instanceID2 = ((Object)root).GetInstanceID();
				if (!_rootCache.TryGetValue(instanceID2, out var value2))
				{
					value2 = default(RootInfo);
					if (root.childCount > 300)
					{
						value2.Big = true;
					}
					else
					{
						Il2CppArrayBase<Renderer> componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>();
						for (int i = 0; i < componentsInChildren.Length; i++)
						{
							if (!value2.Has)
							{
								value2.B = componentsInChildren[i].bounds;
								value2.Has = true;
							}
							else
							{
								((Bounds)(ref value2.B)).Encapsulate(componentsInChildren[i].bounds);
							}
						}
					}
					if (_rootCache.Count > 2000)
					{
						_rootCache.Clear();
					}
					_rootCache[instanceID2] = value2;
				}
				if (value2.Big)
				{
					return true;
				}
				if (!value2.Has)
				{
					return normal.y > 0.7f;
				}
				Bounds b = value2.B;
				((Bounds)(ref b)).Expand(0.15f);
				return ((Bounds)(ref b)).Contains(point);
			}
			catch (Exception)
			{
				return true;
			}
		}

		private static void LogDropHit(RaycastHit hit, bool real)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			Collider collider = ((RaycastHit)(ref hit)).collider;
			int layer = ((Component)collider).gameObject.layer;
			MelonLogger.Msg("[SimpleBlood] drop hit: " + ((Object)collider).name + " layer=" + layer + " (" + LayerMask.LayerToName(layer) + ") trigger=" + collider.isTrigger + " rb=" + ((Object)(object)((RaycastHit)(ref hit)).rigidbody != (Object)null) + " ny=" + ((RaycastHit)(ref hit)).normal.y + " real=" + real);
		}

		private static void OnDropletHit(Droplet d, RaycastHit hit, Vector3 vel)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0060: 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_009d: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: 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_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: 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_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: 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)
			bool flag = SurfaceLooksReal(((RaycastHit)(ref hit)).collider, ((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal);
			if (_hitLogs < 24)
			{
				_hitLogs++;
				LogDropHit(hit, flag);
			}
			else if (((RaycastHit)(ref hit)).normal.y > 0.7f && _floorLogs < 8)
			{
				_floorLogs++;
				LogDropHit(hit, flag);
			}
			if (!Settings.Splats.Value || !flag || ((Object)(object)((RaycastHit)(ref hit)).rigidbody != (Object)null && !((RaycastHit)(ref hit)).rigidbody.isKinematic))
			{
				return;
			}
			Vector3 normal = ((RaycastHit)(ref hit)).normal;
			float magnitude = ((Vector3)(ref vel)).magnitude;
			Vector3 val = vel / Mathf.Max(magnitude, 0.001f);
			float num = 1f - Mathf.Abs(Vector3.Dot(val, normal));
			float num2 = d.Size * Random.Range(6f, 12f) * Settings.SplatSize.Value * Mathf.Clamp(0.6f + magnitude * 0.08f, 0.6f, 1.6f);
			bool flag2 = normal.y > 0.7f;
			if (flag2)
			{
				float num3 = d.Size / 0.02f;
				float volume = Mathf.Clamp(num3 * num3, 0.3f, 8f);
				if (AddToPool(((RaycastHit)(ref hit)).point, normal, volume, ((Component)((RaycastHit)(ref hit)).collider).transform))
				{
					return;
				}
			}
			Sprite sprite = ((num2 < 0.09f) ? PickSprite(_dropSprites) : PickSprite(_splatSprites));
			float sx = num2;
			float sy = num2;
			Vector3 upHint = Vector3.zero;
			if (num > 0.55f)
			{
				sy = num2 * (1f + (num - 0.55f) * 3.5f);
				upHint = Vector3.ProjectOnPlane(val, normal);
			}
			Transform transform = ((Component)((RaycastHit)(ref hit)).collider).transform;
			Anchor(PlaceSplat(sprite, ((RaycastHit)(ref hit)).point, normal, upHint, sx, sy, 0.92f), transform);
			if (flag2 && num2 > 0.1f)
			{
				int num4 = Random.Range(1, 4);
				for (int i = 0; i < num4; i++)
				{
					Vector3 val2 = Vector3.Cross(normal, Random.onUnitSphere);
					if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f))
					{
						((Vector3)(ref val2)).Normalize();
						Vector3 val3 = Vector3.Cross(normal, val2);
						Vector2 val4 = Random.insideUnitCircle * (num2 * 1.15f);
						float num5 = num2 * Random.Range(0.12f, 0.28f);
						Anchor(PlaceSplat(PickSprite(_dropSprites), ((RaycastHit)(ref hit)).point + val2 * val4.x + val3 * val4.y, normal, Vector3.zero, num5, num5, 0.9f), transform);
					}
				}
			}
			else if (Mathf.Abs(normal.y) < 0.5f && num2 > 0.08f && Settings.WallRuns.Value && Random.value < 0.3f)
			{
				StartRunner(((RaycastHit)(ref hit)).point, normal, num2);
			}
		}

		private static long CellKey(Vector3 p)
		{
			//IL_0000: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			long num = Mathf.FloorToInt(p.x / 0.3f);
			long num2 = Mathf.FloorToInt(p.y / 0.3f);
			long num3 = Mathf.FloorToInt(p.z / 0.3f);
			return (num * 73856093) ^ (num2 * 19349663) ^ (num3 * 83492791);
		}

		private static float PoolTarget(float amount)
		{
			return Mathf.Min(Settings.PoolSize.Value, 0.12f + 0.07f * Mathf.Sqrt(amount));
		}

		private static bool AddToPool(Vector3 pos, Vector3 normal, float volume, Transform anchor)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.Pools.Value || !Settings.Splats.Value)
			{
				return false;
			}
			FloorPool floorPool = null;
			float num = float.MaxValue;
			for (int i = 0; i < _pools.Count; i++)
			{
				FloorPool floorPool2 = _pools[i];
				if (floorPool2.S.Active && floorPool2.S.Version == floorPool2.Version)
				{
					float num2 = Vector3.Distance(floorPool2.Pos, pos);
					float num3 = 0.1f + floorPool2.Size * 0.5f;
					if (num2 < num3 && num2 < num)
					{
						floorPool = floorPool2;
						num = num2;
					}
				}
			}
			if (floorPool != null)
			{
				floorPool.Amount += volume;
				floorPool.Target = PoolTarget(floorPool.Amount);
				return num < floorPool.Size * 0.4f;
			}
			long key = CellKey(pos);
			_pending.TryGetValue(key, out var value);
			value += volume;
			if (value < 5f)
			{
				if (_pending.Count > 300)
				{
					_pending.Clear();
				}
				_pending[key] = value;
				return false;
			}
			_pending.Remove(key);
			CreatePool(pos, normal, value, anchor);
			return false;
		}

		private static void CreatePool(Vector3 pos, Vector3 normal, float amount, Transform anchor)
		{
			//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_0022: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			if (_pools.Count >= 50)
			{
				RemovePool(0);
			}
			FloorPool floorPool = new FloorPool();
			floorPool.Pos = pos;
			floorPool.Normal = normal;
			floorPool.Amount = amount;
			floorPool.Size = 0.1f;
			floorPool.Target = PoolTarget(amount);
			floorPool.S = PlaceSplat(PickSprite(_puddleSprites), pos, normal, Random.onUnitSphere, floorPool.Size, floorPool.Size, 0.96f);
			floorPool.S.Pinned = true;
			floorPool.Version = floorPool.S.Version;
			Anchor(floorPool.S, anchor);
			if (Settings.Gloss.Value)
			{
				floorPool.G = PlaceGloss(pos, normal, floorPool.Size * 0.8f, 0.18f);
				floorPool.G.Pinned = true;
				floorPool.GVersion = floorPool.G.Version;
				Anchor(floorPool.G, anchor);
			}
			_pools.Add(floorPool);
		}

		private static void RemovePool(int index)
		{
			FloorPool floorPool = _pools[index];
			if (floorPool.S.Active && floorPool.S.Version == floorPool.Version)
			{
				Deactivate(floorPool.S);
			}
			if (floorPool.G != null && floorPool.G.Active && floorPool.G.Version == floorPool.GVersion)
			{
				Deactivate(floorPool.G);
			}
			_pools.RemoveAt(index);
		}

		private static void TickPools(float dt)
		{
			//IL_00f2: 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)
			if (_pools.Count == 0)
			{
				return;
			}
			for (int num = _pools.Count - 1; num >= 0; num--)
			{
				FloorPool floorPool = _pools[num];
				if (!floorPool.S.Active || floorPool.S.Version != floorPool.Version)
				{
					if (floorPool.G != null && floorPool.G.Active && floorPool.G.Version == floorPool.GVersion)
					{
						Deactivate(floorPool.G);
					}
					_pools.RemoveAt(num);
				}
				else if (Mathf.Abs(floorPool.Target - floorPool.Size) > 0.002f)
				{
					floorPool.Size += (floorPool.Target - floorPool.Size) * Mathf.Min(1f, dt * 1.5f);
					floorPool.S.Tr.localScale = new Vector3(floorPool.Size, floorPool.Size, 1f);
					if (floorPool.G != null && floorPool.G.Active && floorPool.G.Version == floorPool.GVersion)
					{
						floorPool.G.Tr.localScale = new Vector3(floorPool.Size * 0.8f, floorPool.Size * 0.8f, 1f);
					}
				}
			}
		}

		private static void StartRunner(Vector3 point, Vector3 n, float size)
		{
			//IL_000f: 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_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if (_runners.Count < 40)
			{
				Vector3 val = Vector3.ProjectOnPlane(Vector3.down, n);
				if (!(((Vector3)(ref val)).sqrMagnitude < 0.05f))
				{
					((Vector3)(ref val)).Normalize();
					Runner runner = new Runner();
					runner.Normal = n;
					runner.Down = val;
					runner.Top = point;
					runner.Width = Mathf.Clamp(size * 0.2f, 0.012f, 0.04f);
					runner.MaxLen = Mathf.Clamp(size * Random.Range(2f, 5f), 0.15f, 0.9f);
					runner.Speed = Random.Range(0.05f, 0.12f);
					runner.Len = 0.02f;
					runner.S = PlaceSplat(_runSprite, point, n, -val, runner.Width, runner.Len * 0.25f, 0.85f);
					runner.Version = runner.S.Version;
					float num = runner.Width * 2.4f;
					runner.Head = PlaceSplat(PickSprite(_dropSprites), point, n, Vector3.zero, num, num, 0.9f);
					runner.HeadVersion = runner.Head.Version;
					_runners.Add(runner);
				}
			}
		}

		private static void TickRunners(float dt)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_0174: 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 (_runners.Count == 0)
			{
				return;
			}
			for (int num = _runners.Count - 1; num >= 0; num--)
			{
				Runner runner = _runners[num];
				if (!runner.S.Active || runner.S.Version != runner.Version)
				{
					_runners.RemoveAt(num);
				}
				else
				{
					float num2 = 1f - 0.6f * Mathf.Clamp01(runner.Len / runner.MaxLen);
					runner.Len += runner.Speed * num2 * dt;
					if (runner.Len >= runner.MaxLen)
					{
						_runners.RemoveAt(num);
					}
					else
					{
						runner.S.Tr.position = runner.Top + runner.Down * (runner.Len * 0.5f) + runner.Normal * 0.006f;
						runner.S.Tr.localScale = new Vector3(runner.Width, runner.Len * 0.25f, 1f);
						if (runner.Head.Active && runner.Head.Version == runner.HeadVersion)
						{
							runner.Head.Tr.position = runner.Top + runner.Down * runner.Len + runner.Normal * 0.007f;
						}
					}
				}
			}
		}

		private static void TickWounds(float now, float dt)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			if (_wounds.Count == 0 || dt <= 0f)
			{
				return;
			}
			for (int num = _wounds.Count - 1; num >= 0; num--)
			{
				Wound wound = _wounds[num];
				if ((Object)(object)wound.Parent == (Object)null || !((Component)wound.Parent).gameObject.activeInHierarchy)
				{
					_wounds.RemoveAt(num);
				}
				else
				{
					float num2 = (now - wound.Start) / wound.Duration;
					if (num2 >= 1f || !Settings.Bleeding.Value)
					{
						_wounds.RemoveAt(num);
					}
					else
					{
						bool flag = (Object)(object)wound.Pm != (Object)null && wound.Pm.isDead;
						float num3 = Mathf.Pow(1f - num2, 1.4f);
						float num4 = 16f * wound.Intensity * Settings.BleedIntensity.Value * num3 * (flag ? 1.4f : 1f);
						float num5 = 1f;
						if (flag || wound.Intensity > 1.1f)
						{
							float num6 = Mathf.Max(0f, Mathf.Sin(now * 8.5f));
							num5 = 0.35f + 1.9f * num6 * num6 * num6;
						}
						wound.Acc += num4 * num5 * dt;
						while (wound.Acc >= 1f)
						{
							wound.Acc -= 1f;
							Vector3 val = wound.Parent.TransformPoint(wound.LocalPos);
							Vector3 val2 = wound.Parent.TransformDirection(wound.LocalDir);
							SpawnDroplet(vel: RandomInCone(val2, 28f) * (Mathf.Lerp(0.4f, 2.6f, Random.value) * (0.7f + 0.5f * num5)), pos: val + val2 * 0.015f, size: DropletDiameter() * 0.9f, mist: false, life: 2.2f);
						}
					}
				}
			}
		}

		private static void DeathBurst(Corpse c)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_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)
			int num = 0;
			for (int i = 0; i < _wounds.Count; i++)
			{
				if (num >= 3)
				{
					break;
				}
				Wound wound = _wounds[i];
				if (wound.PmId == c.Id && !((Object)(object)wound.Parent == (Object)null))
				{
					num++;
					wound.Duration = Time.time - wound.Start + Settings.BleedSeconds.Value * 1.3f;
					wound.Intensity = Mathf.Min(2f, wound.Intensity * 1.4f);
					Vector3 val = wound.Parent.TransformPoint(wound.LocalPos);
					Vector3 val2 = wound.Parent.TransformDirection(wound.LocalDir);
					for (int j = 0; j < 14; j++)
					{
						Vector3 vel = RandomInCone(val2, 35f) * Mathf.Lerp(1.5f, 5f, Random.value);
						SpawnDroplet(val + val2 * 0.02f, vel, DropletDiameter(), mist: false, 2.2f);
					}
				}
			}
		}

		private static void TickCorpses(float now)
		{
			//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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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_0164: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			for (int num = _corpses.Count - 1; num >= 0; num--)
			{
				Corpse corpse = _corpses[num];
				if ((Object)(object)corpse.Pm == (Object)null || !((Component)corpse.Pm).gameObject.activeInHierarchy)
				{
					_corpses.RemoveAt(num);
				}
				else if (!(now < corpse.NextCheck))
				{
					float num2 = Mathf.Min(0.5f, now - corpse.LastCheck);
					corpse.LastCheck = now;
					corpse.NextCheck = now + 0.1f;
					if (!corpse.BrainDead && !corpse.Pm.isDead)
					{
						corpse.WasDead = false;
					}
					else
					{
						if (!corpse.WasDead)
						{
							corpse.WasDead = true;
							corpse.HasLast = false;
							corpse.HasTrailStart = false;
							corpse.TrailLeft = Settings.TrailLength.Value * Mathf.Clamp01(corpse.Blood / 40f);
							if (!corpse.Cached)
							{
								corpse.Cached = true;
								Il2CppArrayBase<Rigidbody> componentsInChildren = ((Component)corpse.Pm).GetComponentsInChildren<Rigidbody>();
								for (int i = 0; i < componentsInChildren.Length; i++)
								{
									corpse.Bodies.Add(componentsInChildren[i]);
								}
							}
							DeathBurst(corpse);
						}
						Vector3 val = CorpseCenter(corpse);
						if (!CastWorld(val + Vector3.up * 0.35f, Vector3.down, 1.4f, out var result))
						{
							corpse.Last = val;
							corpse.HasLast = true;
						}
						else
						{
							Vector3 point = ((RaycastHit)(ref result)).point;
							Vector3 normal = ((RaycastHit)(ref result)).normal;
							float num3 = (corpse.HasLast ? Vector3.Distance(val, corpse.Last) : 0f);
							float num4 = ((num2 > 0.0001f) ? (num3 / num2) : 0f);
							if (!corpse.HasTrailStart)
							{
								corpse.HasTrailStart = true;
								corpse.LastTrailGround = point;
							}
							if (corpse.Blood > 0.05f && Settings.Pools.Value && Settings.Splats.Value && num4 < 0.6f)
							{
								float num5 = corpse.Blood * (1f - Mathf.Exp((0f - num2) * 3f / Mathf.Max(3f, Settings.PoolGrowSeconds.Value)));
								num5 = Mathf.Min(num5, corpse.Blood);
								if (num5 > 0f)
								{
									AddToPool(point, normal, num5, ((Component)((RaycastHit)(ref result)).collider).transform);
									corpse.Blood -= num5;
								}
							}
							if (Settings.Trails.Value && Settings.Splats.Value && corpse.TrailLeft > 0f && corpse.HasLast && num4 > 0.3f)
							{
								UpdateTrail(corpse, val, point, normal, ((Component)((RaycastHit)(ref result)).collider).transform);
							}
							corpse.Last = val;
							corpse.HasLast = true;
						}
					}
				}
			}
		}

		private static Vector3 CorpseCenter(Corpse c)
		{
			//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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			int num = 0;
			for (int i = 0; i < c.Bodies.Count; i++)
			{
				Rigidbody val2 = c.Bodies[i];
				if (!((Object)(object)val2 == (Object)null))
				{
					val += val2.position;
					num++;
				}
			}
			if (num == 0)
			{
				return ((Component)c.Pm).transform.position;
			}
			return val / (float)num;
		}

		private static void UpdateTrail(Corpse c, Vector3 center, Vector3 gp, Vector3 gn, Transform anchor)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(gp - c.LastTrailGround, gn);
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 0.22f))
			{
				Vector3 upHint = val / magnitude;
				Vector3 pos = (c.LastTrailGround + gp) * 0.5f;
				float sx = Random.Range(0.28f, 0.5f) * Settings.SplatSize.Value;
				float alpha = Mathf.Lerp(0.4f, 0.92f, Mathf.Clamp01(c.TrailLeft / Mathf.Max(1f, Settings.TrailLength.Value)));
				Anchor(PlaceSplat(_smearSprite, pos, gn, upHint, sx, (magnitude * 1.3f + 0.1f) * 0.5f, alpha), anchor);
				int num = Random.Range(0, 3);
				for (int i = 0; i < num; i++)
				{
					Vector3 val2 = Random.insideUnitSphere * 0.15f;
					SpawnDroplet(center + val2, Vector3.zero, DropletDiameter(), mist: false, 1.5f);
				}
				c.TrailLeft -= magnitude;
				c.Blood = Mathf.Max(0f, c.Blood - magnitude * 3f);
				c.LastTrailGround = gp;
			}
		}

		private static Splat NewSplat()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("blood");
			val.layer = 2;
			val.transform.SetParent(_root, false);
			SpriteRenderer sr = val.AddComponent<SpriteRenderer>();
			val.SetActive(false);
			return new Splat
			{
				Go = val,
				Tr = val.transform,
				Sr = sr
			};
		}

		private static Splat GetSplat()
		{
			int num = Mathf.Max(20, Settings.MaxSplats.Value);
			Splat splat;
			if (_splats.Count < num)
			{
				splat = NewSplat();
				_splats.Add(splat);
			}
			else
			{
				int count = _splats.Count;
				_ring = (_ring + 1) % count;
				splat = _splats[_ring];
				for (int i = 0; i < 12; i++)
				{
					if (!splat.Pinned)
					{
						break;
					}
					_ring = (_ring + 1) % count;
					splat = _splats[_ring];
				}
			}
			splat.Version++;
			splat.Active = true;
			splat.Pinned = false;
			splat.Gloss = false;
			splat.HasAnchor = false;
			splat.Anchor = null;
			splat.Go.SetActive(true);
			return splat;
		}

		private static void Anchor(Splat s, Transform t)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)t == (Object)null))
			{
				s.Anchor = t;
				s.AnchorLocal = t.InverseTransformPoint(s.Tr.position);
				s.HasAnchor = true;
			}
		}

		private static bool AnchorOk(Splat s)
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform anchor = s.Anchor;
				if ((Object)(object)anchor == (Object)null || !((Component)anchor).gameObject.activeInHierarchy)
				{
					return false;
				}
				Vector3 val = anchor.TransformPoint(s.AnchorLocal) - s.Tr.position;
				return ((Vector3)(ref val)).sqrMagnitude < 0.0025f;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static void Deactivate(Splat s)
		{
			s.HasAnchor = false;
			s.Anchor = null;
			s.Active = false;
			s.Pinned = false;
			s.Version++;
			s.Go.SetActive(false);
		}

		private static Splat PlaceSplat(Sprite sprite, Vector3 pos, Vector3 normal, Vector3 upHint, float sx, float sy, float alpha)
		{
			//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_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_004a: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_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_0084: 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_009b: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Splat splat = GetSplat();
			splat.Sr.sprite = sprite;
			_order = (_order + 1) % 29000;
			((Renderer)splat.Sr).sortingOrder = _order;
			Vector3 val = Vector3.ProjectOnPlane(upHint, normal);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.ProjectOnPlane(Random.onUnitSphere, normal);
			}
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				val = Vector3.up;
			}
			((Vector3)(ref val)).Normalize();
			Quaternion val2 = Quaternion.LookRotation(-normal, val);
			splat.Tr.SetPositionAndRotation(pos + normal * (0.006f + 0.0015f * (float)(splat.Version % 4)), val2);
			splat.Tr.localScale = new Vector3(sx, sy, 1f);
			splat.Born = Time.time;
			splat.Alpha = alpha;
			splat.Sr.color = BloodColor(0f, alpha);
			return splat;
		}

		private static Splat PlaceGloss(Vector3 pos, Vector3 normal, float size, float alpha)
		{
			//IL_0005: 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_0007: 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)
			Splat splat = PlaceSplat(_glossSprite, pos, normal, Random.onUnitSphere, size, size, 1f);
			splat.Gloss = true;
			splat.GlossAlpha = alpha;
			splat.Sr.color = new Color(1f, 0.82f, 0.82f, alpha);
			return splat;
		}

		private static void UpdateColors(float now)
		{
			//IL_00fd: 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)
			int count = _splats.Count;
			if (count == 0)
			{
				return;
			}
			int num = Mathf.Min(count, 48);
			for (int i = 0; i < num; i++)
			{
				_colorCursor = (_colorCursor + 1) % count;
				Splat splat = _splats[_colorCursor];
				if (!splat.Active)
				{
					continue;
				}
				if (splat.HasAnchor && !AnchorOk(splat))
				{
					Deactivate(splat);
					continue;
				}
				float num2 = now - splat.Born;
				if (splat.Gloss)
				{
					float num3 = (Settings.Drying.Value ? Mathf.Clamp01(1f - num2 / Mathf.Max(5f, Settings.DryTime.Value * 0.7f)) : 1f);
					splat.Sr.color = new Color(1f, 0.82f, 0.82f, Settings.Gloss.Value ? (splat.GlossAlpha * num3) : 0f);
				}
				else
				{
					splat.Sr.color = BloodColor(num2, splat.Alpha);
				}
			}
		}

		private static Color BloodColor(float age, float alpha)
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			float num = (Settings.Drying.Value ? Mathf.Clamp01(age / Mathf.Max(5f, Settings.DryTime.Value)) : 0f);
			float num2 = num * num * (3f - 2f * num);
			Color fresh = Settings.Fresh;
			Color dry = Settings.Dry;
			float num3 = Mathf.Clamp01(1f - age / 8f);
			float num4 = Settings.Brightness.Value * (1f + 0.3f * num3);
			return new Color(Mathf.Lerp(fresh.r, dry.r, num2) * num4, Mathf.Lerp(fresh.g, dry.g, num2) * num4, Mathf.Lerp(fresh.b, dry.b, num2) * num4, alpha * Mathf.Lerp(1f, 0.88f, num2));
		}

		private static Sprite PickSprite(Sprite[] arr)
		{
			return arr[Random.Range(0, arr.Length)];
		}

		private static void GenerateTextures()
		{
			_splatSprites = (Sprite[])(object)new Sprite[5]
			{
				GenSplat(11, 96, 11, 0.17f, 0.26f, 0.47f, 8),
				GenSplat(23, 96, 13, 0.15f, 0.22f, 0.46f, 10),
				GenSplat(37, 96, 9, 0.2f, 0.28f, 0.44f, 7),
				GenSplat(41, 96, 14, 0.13f, 0.24f, 0.47f, 12),
				GenSplat(59, 96, 12, 0.16f, 0.3f, 0.48f, 9)
			};
			_dropSprites = (Sprite[])(object)new Sprite[3]
			{
				GenSplat(53, 64, 4, 0.2f, 0.22f, 0.36f, 3),
				GenSplat(67, 64, 3, 0.24f, 0.2f, 0.32f, 2),
				GenSplat(79, 64, 5, 0.18f, 0.22f, 0.4f, 4)
			};
			_puddleSprites = (Sprite[])(object)new Sprite[3]
			{
				GenPuddle(5, 96),
				GenPuddle(9, 96),
				GenPuddle(14, 96)
			};
			_smearSprite = GenSmear(3, 64, 128);
			_runSprite = GenRun(32, 128);
			_glossSprite = GenGloss(64);
			_dotSprite = GenDot(32);
		}

		private static float Smooth(float e0, float e1, float x)
		{
			float num = Mathf.Clamp01((x - e0) / (e1 - e0));
			return num * num * (3f - 2f * num);
		}

		private static Sprite MakeSprite(Texture2D tex, float ppu)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			((Texture)tex).wrapMode = (TextureWrapMode)1;
			((Texture)tex).filterMode = (FilterMode)1;
			((Object)tex).hideFlags = (HideFlags)32;
			tex.Apply(false);
			Sprite obj = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), ppu);
			((Object)obj).hideFlags = (HideFlags)32;
			return obj;
		}

		private static Sprite GenSplat(int seed, int size, int spikes, float blobR, float spikeMin, float spikeMax, int specks)
		{
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			Random random = new Random(seed);
			float[] array = new float[spikes];
			float[] array2 = new float[spikes];
			float[] array3 = new float[spikes];
			for (int i = 0; i < spikes; i++)
			{
				array[i] = (float)(random.NextDouble() * Math.PI * 2.0);
				array2[i] = spikeMin + (float)random.NextDouble() * (spikeMax - spikeMin);
				array3[i] = 0.016f + (float)random.NextDouble() * 0.04f;
			}
			float[] array4 = new float[specks];
			float[] array5 = new float[specks];
			float[] array6 = new float[specks];
			for (int j = 0; j < specks; j++)
			{
				array4[j] = (float)(random.NextDouble() * Math.PI * 2.0);
				array5[j] = 0.26f + (float)random.NextDouble() * 0.2f;
				array6[j] = 0.008f + (float)random.NextDouble() * 0.02f;
			}
			float num = (float)(random.NextDouble() * 6.28);
			float num2 = (float)(random.NextDouble() * 6.28);
			float num3 = (float)(random.NextDouble() * 6.28);
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			for (int k = 0; k < size; k++)
			{
				for (int l = 0; l < size; l++)
				{
					float num4 = ((float)l + 0.5f) / (float)size - 0.5f;
					float num5 = ((float)k + 0.5f) / (float)size - 0.5f;
					float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5);
					float num7 = Mathf.Atan2(num5, num4);
					float num8 = blobR * (1f + 0.2f * Mathf.Sin(3f * num7 + num) + 0.12f * Mathf.Sin(5f * num7 + num2) + 0.08f * Mathf.Sin(9f * num7 + num3));
					float num9 = Smooth(num8 + 0.012f, num8 - 0.012f, num6);
					for (int m = 0; m < spikes; m++)
					{
						float num10 = num7 - array[m];
						float num11 = Mathf.Cos(num10);
						if (!(num11 <= 0f))
						{
							float num12 = num6 * num11;
							if (!(num12 > array2[m]))
							{
								float x = Mathf.Abs(num6 * Mathf.Sin(num10));
								float num13 = array3[m] * Mathf.Pow(Mathf.Clamp01(1f - num12 / array2[m]), 0.65f) + 0.004f;
								num9 = Mathf.Max(num9, Smooth(num13, num13 * 0.55f, x));
							}
						}
					}
					for (int n = 0; n < specks; n++)
					{
						float num14 = num4 - Mathf.Cos(array4[n]) * array5[n];
						float num15 = num5 - Mathf.Sin(array4[n]) * array5[n];
						float x2 = Mathf.Sqrt(num14 * num14 + num15 * num15);
						num9 = Mathf.Max(num9, Smooth(array6[n], array6[n] * 0.6f, x2));
					}
					float num16 = Smooth(num8, 0f, num6);
					float num17 = 1f - 0.28f * num16;
					val.SetPixel(l, k, new Color(num17, num17, num17, num9));
				}
			}
			return MakeSprite(val, size);
		}

		private static Sprite GenPuddle(int seed, int size)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			Random random = new Random(seed);
			float num = (float)(random.NextDouble() * 6.28);
			float num2 = (float)(random.NextDouble() * 6.28);
			float num3 = (float)(random.NextDouble() * 6.28);
			float num4 = (float)(random.NextDouble() * 6.28);
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num5 = ((float)j + 0.5f) / (float)size - 0.5f;
					float num6 = ((float)i + 0.5f) / (float)size - 0.5f;
					float x = Mathf.Sqrt(num5 * num5 + num6 * num6);
					float num7 = Mathf.Atan2(num6, num5);
					float num8 = 0.38f * (1f + 0.12f * Mathf.Sin(2f * num7 + num) + 0.1f * Mathf.Sin(3f * num7 + num2) + 0.07f * Mathf.Sin(5f * num7 + num3) + 0.04f * Mathf.Sin(7f * num7 + num4));
					float num9 = Smooth(num8, num8 - 0.06f, x);
					num9 *= Mathf.Lerp(1f, 0.8f, Smooth(num8 * 0.55f, num8, x));
					float num10 = Smooth(num8, 0f, x);
					float num11 = 1f - 0.2f * num10;
					val.SetPixel(j, i, new Color(num11, num11, num11, num9));
				}
			}
			return MakeSprite(val, size);
		}

		private static Sprite GenSmear(int seed, int w, int h)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, false);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num = ((float)i + 0.5f) / (float)h;
					float num2 = (((float)j + 0.5f) / (float)w - 0.5f) * 2f;
					float num3 = Mathf.Pow(Mathf.Sin((float)Math.PI * Mathf.Clamp01(num * 0.9f + 0.05f)), 0.5f) * (1f - 0.35f * num);
					float num4 = Mathf.PerlinNoise(num2 * 3f + (float)seed, num * 6f);
					float num5 = num3 * (0.85f + 0.25f * (num4 - 0.5f));
					float num6 = 0.7f + 0.3f * Mathf.PerlinNoise(num2 * 14f + 5f, num * 2f + (float)seed);
					float num7 = Smooth(num5, num5 * 0.6f, Mathf.Abs(num2)) * num6 * (1f - 0.55f * num * num);
					float num8 = 0.9f + 0.1f * num6;
					val.SetPixel(j, i, new Color(num8, num8, num8, Mathf.Clamp01(num7)));
				}
			}
			return MakeSprite(val, w);
		}

		private static Sprite GenRun(int w, int h)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, false);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num = ((float)i + 0.5f) / (float)h;
					float num2 = (((float)j + 0.5f) / (float)w - 0.5f) * 2f;
					float num3 = 0.34f + 0.06f * Mathf.PerlinNoise(num * 5f, 3.7f);
					float num4 = Smooth(num3, num3 * 0.45f, Mathf.Abs(num2));
					num4 *= 1f - 0.85f * num * num;
					val.SetPixel(j, i, new Color(0.92f, 0.92f, 0.92f, Mathf.Clamp01(num4)));
				}
			}
			return MakeSprite(val, w);
		}

		private static Sprite GenGloss(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = ((float)j + 0.5f) / (float)size - 0.5f;
					float num2 = ((float)i + 0.5f) / (float)size - 0.5f;
					float x = Mathf.Sqrt(num * num + num2 * num2);
					float num3 = num + 0.12f;
					float num4 = num2 - 0.1f;
					float x2 = Mathf.Sqrt(num3 * num3 + num4 * num4);
					float num5 = Smooth(0.3f, 0f, x2) * 0.85f * Smooth(0.46f, 0.38f, x);
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num5));
				}
			}
			return MakeSprite(val, size);
		}

		private static Sprite GenDot(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = ((float)j + 0.5f) / (float)size - 0.5f;
					float num2 = ((float)i + 0.5f) / (float)size - 0.5f;
					float x = Mathf.Sqrt(num * num + num2 * num2);
					float num3 = Smooth(0.5f, 0.28f, x);
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num3));
				}
			}
			return MakeSprite(val, size);
		}
	}
	public class Main : MelonMod
	{
		private float _nextErrorLog;

		public override void OnInitializeMelon()
		{
			Settings.Init();
			Hooking.OnLevelLoaded += delegate
			{
				BloodManager.EnsureInit();
			};
			Hooking.OnLevelUnloaded += BloodManager.ClearAll;
			Hooking.OnNPCBrainDie += BloodManager.OnBrainDie;
			Hooking.OnNPCBrainResurrected += BloodManager.OnBrainResurrected;
			Settings.BuildMenu();
			MelonLogger.Msg("SimpleBlood loaded. Open BoneMenu -> SimpleBlood.");
		}

		public override void OnLateUpdate()
		{
			try
			{
				BloodManager.Tick();
				Settings.Tick();
			}
			catch (Exception ex)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (realtimeSinceStartup > _nextErrorLog)
				{
					_nextErrorLog = realtimeSinceStartup + 5f;
					MelonLogger.Error("SimpleBlood tick error: " + ex);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")]
	public static class Patch_NpcTakeDamage
	{
		public static void Postfix(SubBehaviourHealth __instance, int m, Attack attack, float __result)
		{
			try
			{
				BloodManager.OnNpcHit(__instance, attack, __result);
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SimpleBlood hit error: " + ex);
			}
		}
	}
	public enum ApplyMode
	{
		AllNPCs,
		NameFilter
	}
	public static class Settings
	{
		private static MelonPreferences_Category _cat;

		private static float _saveAt = -1f;

		public static MelonPreferences_Entry<bool> Enabled;

		public static MelonPreferences_Entry<int> Mode;

		public static MelonPreferences_Entry<string> NameFilter;

		public static MelonPreferences_Entry<bool> OrganicOnly;

		public static MelonPreferences_Entry<bool> Debug;

		public static MelonPreferences_Entry<int> Droplets;

		public static MelonPreferences_Entry<float> SprayPower;

		public static MelonPreferences_Entry<float> SprayAngle;

		public static MelonPreferences_Entry<float> BackSpray;

		public static MelonPreferences_Entry<float> DropletSize;

		public static MelonPreferences_Entry<bool> Mist;

		public static MelonPreferences_Entry<bool> Bleeding;

		public static MelonPreferences_Entry<float> BleedSeconds;

		public static MelonPreferences_Entry<float> BleedIntensity;

		public static MelonPreferences_Entry<bool> Splats;

		public static MelonPreferences_Entry<int> MaxSplats;

		public static MelonPreferences_Entry<float> SplatSize;

		public static MelonPreferences_Entry<float> Brightness;

		public static MelonPreferences_Entry<bool> WallRuns;

		public static MelonPreferences_Entry<bool> Gloss;

		public static MelonPreferences_Entry<bool> ValidateSurfaces;

		public static MelonPreferences_Entry<bool> Pools;

		public static MelonPreferences_Entry<float> PoolSize;

		public static MelonPreferences_Entry<float> PoolGrowSeconds;

		public static MelonPreferences_Entry<bool> Trails;

		public static MelonPreferences_Entry<float> TrailLength;

		public static MelonPreferences_Entry<float> FreshR;

		public static MelonPreferences_Entry<float> FreshG;

		public static MelonPreferences_Entry<float> FreshB;

		public static MelonPreferences_Entry<float> DryR;

		public static MelonPreferences_Entry<float> DryG;

		public static MelonPreferences_Entry<float> DryB;

		public static MelonPreferences_Entry<bool> Drying;

		public static MelonPreferences_Entry<float> DryTime;

		public static Color Fresh => new Color(FreshR.Value, FreshG.Value, FreshB.Value, 0.94f);

		public static Color Dry => new Color(DryR.Value, DryG.Value, DryB.Value, 0.94f);

		public static void Init()
		{
			_cat = MelonPreferences.CreateCategory("SimpleBlood");
			Enabled = _cat.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Mode = _cat.CreateEntry<int>("ApplyMode", 0, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			NameFilter = _cat.CreateEntry<string>("NameFilter", "ford", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			OrganicOnly = _cat.CreateEntry<bool>("OrganicOnly", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Debug = _cat.CreateEntry<bool>("DebugLog", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Droplets = _cat.CreateEntry<int>("DropletsPerHit_v3", 44, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			SprayPower = _cat.CreateEntry<float>("SprayPower", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			SprayAngle = _cat.CreateEntry<float>("SprayAngle", 24f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			BackSpray = _cat.CreateEntry<float>("BackSprayRatio", 0.45f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			DropletSize = _cat.CreateEntry<float>("DropletSize", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Mist = _cat.CreateEntry<bool>("Mist", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Bleeding = _cat.CreateEntry<bool>("Bleeding", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			BleedSeconds = _cat.CreateEntry<float>("BleedSeconds", 10f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			BleedIntensity = _cat.CreateEntry<float>("BleedIntensity", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Splats = _cat.CreateEntry<bool>("Splats", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			MaxSplats = _cat.CreateEntry<int>("MaxSplats_v3", 700, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			SplatSize = _cat.CreateEntry<float>("SplatSize", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Brightness = _cat.CreateEntry<float>("Brightness", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			WallRuns = _cat.CreateEntry<bool>("WallRuns", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Gloss = _cat.CreateEntry<bool>("Gloss_v4", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			ValidateSurfaces = _cat.CreateEntry<bool>("ValidateSurfaces", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Pools = _cat.CreateEntry<bool>("Pools", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			PoolSize = _cat.CreateEntry<float>("PoolSize_v3", 1.3f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			PoolGrowSeconds = _cat.CreateEntry<float>("PoolGrowSeconds", 25f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Trails = _cat.CreateEntry<bool>("Trails", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			TrailLength = _cat.CreateEntry<float>("TrailLength_v3", 9f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			FreshR = _cat.CreateEntry<float>("FreshR", 0.72f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			FreshG = _cat.CreateEntry<float>("FreshG", 0.02f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			FreshB = _cat.CreateEntry<float>("FreshB", 0.03f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			DryR = _cat.CreateEntry<float>("DryR", 0.2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			DryG = _cat.CreateEntry<float>("DryG", 0.025f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			DryB = _cat.CreateEntry<float>("DryB", 0.02f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Drying = _cat.CreateEntry<bool>("Drying", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			DryTime = _cat.CreateEntry<float>("DryTimeSeconds", 120f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		}

		public static void BuildMenu()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("SimpleBlood", Color.red, 0, true);
			AddBool(obj, "Enabled", Enabled);
			obj.CreateEnum("Apply to", Color.white, (Enum)(ApplyMode)Mode.Value, (Action<Enum>)delegate(Enum v)
			{
				Mode.Value = (int)(ApplyMode)(object)v;
				Dirty();
			});
			obj.CreateString("Name filter", Color.white, NameFilter.Value, (Action<string>)delegate(string v)
			{
				NameFilter.Value = v;
				Dirty();
			});
			AddBool(obj, "Organic only", OrganicOnly);
			AddBool(obj, "Debug log", Debug);
			obj.CreateFunction("Clear all blood", Color.yellow, (Action)BloodManager.ClearAll);
			Page p = obj.CreatePage("Spray", Color.red, 0, true);
			AddInt(p, "Droplets per hit", Droplets, 4, 4, 150);
			AddFloat(p, "Spray power", SprayPower, 0.1f, 0.2f, 3f);
			AddFloat(p, "Spray angle", SprayAngle, 2f, 4f, 70f);
			AddFloat(p, "Back spray (to shooter)", BackSpray, 0.05f, 0f, 1f);
			AddFloat(p, "Droplet size", DropletSize, 0.1f, 0.3f, 3f);
			AddBool(p, "Mist", Mist);
			Page p2 = obj.CreatePage("Bleeding", Color.red, 0, true);
			AddBool(p2, "Bleeding wounds", Bleeding);
			AddFloat(p2, "Bleed seconds", BleedSeconds, 1f, 1f, 60f);
			AddFloat(p2, "Bleed intensity", BleedIntensity, 0.1f, 0.1f, 3f);
			Page p3 = obj.CreatePage("Decals", Color.red, 0, true);
			AddBool(p3, "Splats on surfaces", Splats);
			AddInt(p3, "Max splats", MaxSplats, 50, 50, 2000);
			AddFloat(p3, "Splat size", SplatSize, 0.1f, 0.3f, 3f);
			AddFloat(p3, "Brightness", Brightness, 0.05f, 0.2f, 1.6f);
			AddBool(p3, "Blood runs on walls", WallRuns);
			AddBool(p3, "Skip invisible surfaces", ValidateSurfaces);
			Page p4 = obj.CreatePage("Pools and trails", Color.red, 0, true);
			AddBool(p4, "Pools on floor", Pools);
			AddBool(p4, "Wet gloss on pools", Gloss);
			AddFloat(p4, "Pool max size (m)", PoolSize, 0.1f, 0.3f, 3f);
			AddFloat(p4, "Pool grow seconds", PoolGrowSeconds, 1f, 3f, 120f);
			AddBool(p4, "Drag trails", Trails);
			AddFloat(p4, "Trail length (m)", TrailLength, 0.5f, 1f, 30f);
			Page p5 = obj.CreatePage("Color and drying", Color.red, 0, true);
			AddFloat(p5, "Fresh red", FreshR, 0.05f, 0f, 1f);
			AddFloat(p5, "Fresh green", FreshG, 0.05f, 0f, 1f);
			AddFloat(p5, "Fresh blue", FreshB, 0.05f, 0f, 1f);
			AddBool(p5, "Drying", Drying);
			AddFloat(p5, "Dry time (s)", DryTime, 10f, 10f, 600f);
			AddFloat(p5, "Dry red", DryR, 0.05f, 0f, 1f);
			AddFloat(p5, "Dry green", DryG, 0.05f, 0f, 1f);
			AddFloat(p5, "Dry blue", DryB, 0.05f, 0f, 1f);
		}

		public static void Tick()
		{
			if (_saveAt > 0f && Time.realtimeSinceStartup >= _saveAt)
			{
				_saveAt = -1f;
				MelonPreferences.Save();
			}
		}

		private static void Dirty()
		{
			_saveAt = Time.realtimeSinceStartup + 1.5f;
		}

		private static void AddBool(Page p, string name, MelonPreferences_Entry<bool> e)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			p.CreateBool(name, Color.white, e.Value, (Action<bool>)delegate(bool v)
			{
				e.Value = v;
				Dirty();
			});
		}

		private static void AddFloat(Page p, string name, MelonPreferences_Entry<float> e, float inc, float min, float max)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			p.CreateFloat(name, Color.white, e.Value, inc, min, max, (Action<float>)delegate(float v)
			{
				e.Value = v;
				Dirty();
			});
		}

		private static void AddInt(Page p, string name, MelonPreferences_Entry<int> e, int inc, int min, int max)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			p.CreateInt(name, Color.white, e.Value, inc, min, max, (Action<int>)delegate(int v)
			{
				e.Value = v;
				Dirty();
			});
		}
	}
}