Decompiled source of BrainInjuries v2.2.0

Mods/InjuriesMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.PuppetMasta;
using InjuriesMod.Core;
using InjuriesMod.Modules;
using MelonLoader;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(ModClass), "Brain Injuries", "2.2.0", "PolskiAnt", "https://thunderstore.io/c/bonelab/p/PolskiAnt/BrainInjuries/")]
[assembly: AssemblyTitle("Brain Injuries")]
[assembly: AssemblyDescription("Adds a little realism to the game (PATCH 6)")]
[assembly: MelonColor(255, 200, 30, 20)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("InjuriesMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("InjuriesMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace InjuriesMod.Patches
{
	[HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")]
	public static class DamagePatch
	{
		private static readonly Random rnd = new Random();

		public static void Prefix(SubBehaviourHealth __instance, int m, Attack attack)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Invalid comparison between Unknown and I4
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Invalid comparison between Unknown and I4
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Invalid comparison between Unknown and I4
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Invalid comparison between Unknown and I4
			if (__instance.muscles == null || m >= ((Il2CppArrayBase<StunGroup>)(object)__instance.muscles).Count)
			{
				return;
			}
			PuppetMaster puppetMaster = ((SubBehaviourBase)__instance).behaviour.puppetMaster;
			if ((Object)(object)puppetMaster == (Object)null)
			{
				return;
			}
			ReactionContext reactionContext = new ReactionContext(puppetMaster);
			if (!reactionContext.IsValid())
			{
				return;
			}
			string text = ((object)((Il2CppArrayBase<StunGroup>)(object)__instance.muscles)[m]/*cast due to .constrained prefix*/).ToString();
			if (!DeathTracker.PriorityDeathCause.ContainsKey(reactionContext.Ptr))
			{
				DeathTracker.LastHitBone[reactionContext.Ptr] = ((text == "Head" && (int)attack.attackType != 2 && (int)attack.attackType != 1) ? "Unknown" : text);
			}
			if (text == "Head" && (int)attack.attackType == 2 && ModClass.HeadBluntResistEnabled)
			{
				attack.damage *= 0.7f;
			}
			if (text == "Head")
			{
				DeathTracker.LastAttackType[reactionContext.Ptr] = attack.attackType;
				DeathTracker.LastAttackDamage[reactionContext.Ptr] = attack.damage;
				if (attack.damage > 5f && ((int)attack.attackType == 2 || (int)attack.attackType == 1))
				{
					DeathTracker.PriorityDeathCause[reactionContext.Ptr] = "Head";
				}
				if (attack.damage > 2f && attack.damage <= 5f && (int)attack.attackType == 2 && ModClass.UnconsciousEnabled && !DeathTracker.AlreadyDead.Contains(reactionContext.Ptr) && !DeathTracker.UnconsciousNPCs.Contains(reactionContext.Ptr) && rnd.Next(101) <= 50)
				{
					DeathTracker.UnconsciousNPCs.Add(reactionContext.Ptr);
					DeathTracker.UnconsciousStartTime[reactionContext.Ptr] = Time.time;
					MelonCoroutines.Start(ModuleD_Consciousness.Unconscious(reactionContext.Puppet));
				}
			}
			if (text == "Spine" && ModClass.TorsoArmorEnabled)
			{
				attack.damage *= 0.5f;
			}
		}
	}
	[HarmonyPatch(typeof(PuppetMaster), "Kill", new Type[] { })]
	public static class DeathPatch
	{
		public static void Postfix(PuppetMaster __instance)
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			ReactionContext reactionContext = new ReactionContext(__instance);
			if (!reactionContext.IsValid() || DeathTracker.AlreadyDead.Contains(reactionContext.Ptr))
			{
				return;
			}
			DeathTracker.AlreadyDead.Add(reactionContext.Ptr);
			string value;
			string value2;
			string text = (DeathTracker.PriorityDeathCause.TryGetValue(reactionContext.Ptr, out value) ? value : ((!DeathTracker.LastHitBone.TryGetValue(reactionContext.Ptr, out value2)) ? "Unknown" : value2));
			if (!ModClass.BrainInjuriesEnabled)
			{
				text = "Disabled";
			}
			if (DeathTracker.UnconsciousNPCs.Contains(reactionContext.Ptr))
			{
				((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC died while unconscious.");
				PhysicsHelper.ApplyProfile(reactionContext.Puppet);
				DeathTracker.UnconsciousNPCs.Remove(reactionContext.Ptr);
				return;
			}
			((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC died | cause: " + text);
			if (!(text != "Head"))
			{
				AttackType value3;
				AttackType attackType = (AttackType)((!DeathTracker.LastAttackType.TryGetValue(reactionContext.Ptr, out value3)) ? 64 : ((int)value3));
				float value4;
				float damage = (DeathTracker.LastAttackDamage.TryGetValue(reactionContext.Ptr, out value4) ? value4 : 0f);
				MelonCoroutines.Start(ModuleA_Impact.HandleImpact(reactionContext.Puppet, attackType, damage));
			}
		}
	}
	[HarmonyPatch(typeof(PuppetMaster))]
	public static class PuppetMasterLifecyclePatches
	{
		[HarmonyPatch("OnEnable")]
		[HarmonyPostfix]
		public static void OnEnablePostfix(PuppetMaster __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !(((Il2CppObjectBase)__instance).Pointer == IntPtr.Zero))
			{
				IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer;
				if (DeathTracker.TryRegisterSpawn(pointer, out var currentGeneration))
				{
					PhysicsHelper.EnsureBindPoseCached(__instance);
					MelonLogger.Msg($"[Diag] NPC spawned: {pointer}, Gen Token: {currentGeneration}");
				}
			}
		}

		[HarmonyPatch("OnDisable")]
		[HarmonyPrefix]
		public static void OnDisablePrefix(PuppetMaster __instance)
		{
			if ((Object)(object)__instance != (Object)null && ((Il2CppObjectBase)__instance).Pointer != IntPtr.Zero)
			{
				PhysicsHelper.ResetProfile(__instance);
				DeathTracker.ClearNPC(((Il2CppObjectBase)__instance).Pointer);
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		public static void OnDestroyPrefix(PuppetMaster __instance)
		{
			if ((Object)(object)__instance != (Object)null && ((Il2CppObjectBase)__instance).Pointer != IntPtr.Zero)
			{
				PhysicsHelper.ResetProfile(__instance);
				DeathTracker.ClearNPC(((Il2CppObjectBase)__instance).Pointer);
			}
		}
	}
}
namespace InjuriesMod.Modules
{
	public static class JointSpaceHelper
	{
		public static Quaternion GetCurrentRelativeRotation(ConfigurableJoint joint, Quaternion initialLocalRotation)
		{
			//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_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0065: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Vector3 axis = ((Joint)joint).axis;
			Vector3 val = Vector3.Cross(((Joint)joint).axis, joint.secondaryAxis);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			val = Vector3.Cross(normalized, axis);
			Vector3 normalized2 = ((Vector3)(ref val)).normalized;
			Quaternion val2 = Quaternion.LookRotation(normalized, normalized2);
			Quaternion localRotation = ((Component)joint).transform.localRotation;
			Quaternion val3 = Quaternion.Inverse(val2);
			val3 *= Quaternion.Inverse(localRotation) * initialLocalRotation;
			return val3 * val2;
		}
	}
	public static class ModuleA_Impact
	{
		public enum ImmediateReaction
		{
			FlaccidParalysis,
			None,
			Posturing,
			ForwardBuckle,
			Fencing
		}

		public enum PostureTendency
		{
			None,
			Flexor,
			Extensor,
			Mixed
		}

		public static IEnumerator HandleImpact(PuppetMaster puppet, AttackType attackType, float damage)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!ModClass.BrainInjuriesEnabled)
			{
				yield break;
			}
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			ImmediateReaction reaction = ChooseImmediateReaction(attackType, damage);
			if (!ModClass.BrainInjuriesEnabled)
			{
				reaction = ImmediateReaction.None;
			}
			((MelonBase)ModClass.Instance).LoggerInstance.Msg($"[ModuleA] Reaction: {reaction}");
			if (ModClass.SeizuresEnabled)
			{
				if (1 == 0)
				{
				}
				float num = (((int)attackType == 1) ? ModClass.SeizureChancePiercing : (((int)attackType != 2) ? 0f : ModClass.SeizureChanceBlunt));
				if (1 == 0)
				{
				}
				float seizureChance = num;
				if (seizureChance > 0f && DeathTracker.Rng.NextDouble() * 100.0 < (double)seizureChance)
				{
					ModuleC_Seizures.Start(ctx.Ptr, Random.Range(0.5f, 0.9f), Random.Range(5f, 10f));
				}
			}
			yield return MelonCoroutines.Start(RunImmediateReaction(ctx.Puppet, reaction, attackType, damage));
		}

		private static PostureTendency ChoosePostureTendency(AttackType attackType)
		{
			int[] array = new int[3] { 35, 25, 40 };
			PostureTendency[] array2 = new PostureTendency[3]
			{
				PostureTendency.Flexor,
				PostureTendency.Extensor,
				PostureTendency.Mixed
			};
			float num = 0f;
			float[] array3 = new float[array2.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				float multiplier = ModClass.GetMultiplier(ModClass.PosturingSettings[array2[i]]);
				array3[i] = (float)array[i] * multiplier;
				num += array3[i];
			}
			if (num <= 0f)
			{
				return PostureTendency.None;
			}
			double num2 = DeathTracker.Rng.NextDouble() * (double)num;
			float num3 = 0f;
			for (int j = 0; j < array3.Length; j++)
			{
				num3 += array3[j];
				if (num2 < (double)num3)
				{
					return array2[j];
				}
			}
			return array2[0];
		}

		private static ImmediateReaction ChooseImmediateReaction(AttackType attackType, float damage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			if ((int)attackType == 1)
			{
				int[] baseWeights = new int[4] { 40, 15, 25, 20 };
				return WeightedRandom(new ImmediateReaction[4]
				{
					ImmediateReaction.FlaccidParalysis,
					ImmediateReaction.None,
					ImmediateReaction.Posturing,
					ImmediateReaction.ForwardBuckle
				}, baseWeights);
			}
			if ((int)attackType == 2)
			{
				if (damage >= 5f)
				{
					int[] baseWeights2 = new int[5] { 25, 35, 15, 10, 15 };
					return WeightedRandom(new ImmediateReaction[5]
					{
						ImmediateReaction.FlaccidParalysis,
						ImmediateReaction.Posturing,
						ImmediateReaction.Fencing,
						ImmediateReaction.None,
						ImmediateReaction.ForwardBuckle
					}, baseWeights2);
				}
				if (damage >= 2f)
				{
					int[] baseWeights3 = new int[5] { 15, 15, 45, 15, 10 };
					return WeightedRandom(new ImmediateReaction[5]
					{
						ImmediateReaction.FlaccidParalysis,
						ImmediateReaction.Posturing,
						ImmediateReaction.Fencing,
						ImmediateReaction.None,
						ImmediateReaction.ForwardBuckle
					}, baseWeights3);
				}
				int[] baseWeights4 = new int[5] { 20, 5, 0, 60, 15 };
				return WeightedRandom(new ImmediateReaction[5]
				{
					ImmediateReaction.FlaccidParalysis,
					ImmediateReaction.Posturing,
					ImmediateReaction.Fencing,
					ImmediateReaction.None,
					ImmediateReaction.ForwardBuckle
				}, baseWeights4);
			}
			int[] baseWeights5 = new int[3] { 45, 45, 10 };
			return WeightedRandom(new ImmediateReaction[3]
			{
				ImmediateReaction.FlaccidParalysis,
				ImmediateReaction.None,
				ImmediateReaction.ForwardBuckle
			}, baseWeights5);
		}

		private static ImmediateReaction WeightedRandom(ImmediateReaction[] options, int[] baseWeights)
		{
			float num = 0f;
			float[] array = new float[options.Length];
			for (int i = 0; i < options.Length; i++)
			{
				float multiplier = ModClass.GetMultiplier(ModClass.UserSettings[options[i]]);
				array[i] = (float)baseWeights[i] * multiplier;
				num += array[i];
			}
			if (num <= 0f)
			{
				return ImmediateReaction.None;
			}
			double num2 = DeathTracker.Rng.NextDouble() * (double)num;
			float num3 = 0f;
			for (int j = 0; j < array.Length; j++)
			{
				num3 += array[j];
				if (num2 < (double)num3)
				{
					return options[j];
				}
			}
			return options[^1];
		}

		private static IEnumerator RunImmediateReaction(PuppetMaster puppet, ImmediateReaction reaction, AttackType attackType, float damage)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ReactionContext ctx = new ReactionContext(puppet);
			if (ctx.IsValid())
			{
				switch (reaction)
				{
				case ImmediateReaction.Posturing:
				{
					PostureTendency tendency = ChoosePostureTendency(attackType);
					float intensity = Random.Range(0.6f, 1f);
					yield return RunPosturing(onsetDelay: (Random.value < 0.5f) ? 0f : Random.Range(0.1f, 0.4f), blendInTime: Mathf.Lerp(0.5f, 0.15f, intensity), holdTime: Mathf.Lerp(2f, 8f, intensity), puppet: ctx.Puppet, tendency: tendency, intensity: intensity, decayTime: 6f);
					break;
				}
				case ImmediateReaction.FlaccidParalysis:
					yield return FlaccidParalysis(ctx.Puppet);
					break;
				case ImmediateReaction.ForwardBuckle:
					yield return ForwardBuckle(ctx.Puppet);
					break;
				case ImmediateReaction.Fencing:
					yield return Fencing(ctx.Puppet);
					break;
				case ImmediateReaction.None:
					yield return Collapse(ctx.Puppet);
					break;
				}
			}
		}

		private static IEnumerator RunPosturing(PuppetMaster puppet, PostureTendency tendency, float intensity, float onsetDelay, float blendInTime, float holdTime, float decayTime)
		{
			if (tendency == PostureTendency.None || intensity <= 0f)
			{
				yield break;
			}
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
			if (onsetDelay > 0f)
			{
				float delayTimer = 0f;
				while (delayTimer < onsetDelay)
				{
					if (ctx.IsValid())
					{
						delayTimer += Time.deltaTime;
						yield return null;
						continue;
					}
					yield break;
				}
			}
			if (!ctx.IsValid())
			{
				yield break;
			}
			Quaternion flexElbow = Quaternion.Euler(50f, 0f, 0f);
			Quaternion flexWrist = Quaternion.Euler(50f, 0f, 0f);
			Quaternion flexShoulder = Quaternion.Euler(0f, 0f, 0f);
			Quaternion extendKneeSubtle = Quaternion.Euler(-8f, 0f, 0f);
			Quaternion extendAnkleSubtle = Quaternion.Euler(-20f, 0f, 0f);
			Quaternion extElbow = Quaternion.Euler(-50f, 0f, 0f);
			Quaternion extWrist = Quaternion.Euler(-40f, 0f, 0f);
			Quaternion extShoulder = Quaternion.Euler(-15f, 0f, -15f);
			Quaternion extendKnee = Quaternion.Euler(15f, 0f, 0f);
			Quaternion extendAnkle = Quaternion.Euler(20f, 0f, 0f);
			float totalDuration = blendInTime + holdTime + decayTime;
			float e = 0f;
			try
			{
				while (e < totalDuration && ctx.IsValid())
				{
					ModuleC_Seizures.Tick(ctx.Ptr);
					float strength = ((e < blendInTime) ? (Mathf.Clamp01(e / blendInTime) * intensity) : ((!(e < blendInTime + holdTime)) ? Mathf.Lerp(intensity, 0f, (e - blendInTime - holdTime) / decayTime) : intensity));
					if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var bindPose))
					{
						bindPose = PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
					}
					Dictionary<string, Quaternion> livePose = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, bindPose);
					foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (muscle == null)
						{
							continue;
						}
						string name = muscle.name.ToLower();
						ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
						if ((Object)(object)joint == (Object)null || !livePose.TryGetValue(muscle.name, out var currentPose))
						{
							continue;
						}
						bool isKnee = name.Contains("knee");
						bool isAnkle = name.Contains("ankle");
						bool isElbow = name.Contains("elbow");
						bool isWrist = name.Contains("wrist");
						bool isShoulder = name.Contains("shoulder");
						bool isLeg = isKnee || isAnkle || name.Contains("hip");
						Quaternion offset = Quaternion.identity;
						bool matched = true;
						switch (tendency)
						{
						case PostureTendency.Flexor:
							if (isElbow)
							{
								offset = flexElbow;
							}
							else if (isWrist)
							{
								offset = flexWrist;
							}
							else if (isShoulder)
							{
								offset = flexShoulder;
							}
							else if (isKnee)
							{
								offset = extendKneeSubtle;
							}
							else if (isAnkle)
							{
								offset = extendAnkleSubtle;
							}
							else
							{
								matched = false;
							}
							break;
						case PostureTendency.Extensor:
							if (isElbow)
							{
								offset = extElbow;
							}
							else if (isWrist)
							{
								offset = extWrist;
							}
							else if (isShoulder)
							{
								offset = extShoulder;
							}
							else if (isKnee)
							{
								offset = extendKnee;
							}
							else if (isAnkle)
							{
								offset = extendAnkle;
							}
							else
							{
								matched = false;
							}
							break;
						case PostureTendency.Mixed:
							if (isElbow)
							{
								offset = flexElbow;
							}
							else if (isWrist)
							{
								offset = flexWrist;
							}
							else if (isShoulder)
							{
								offset = flexShoulder;
							}
							else if (isKnee)
							{
								offset = extendKnee;
							}
							else if (isAnkle)
							{
								offset = extendAnkle;
							}
							else
							{
								matched = false;
							}
							break;
						}
						if (matched)
						{
							(float, float) modifiers = ModuleC_Seizures.GetModifiers(ctx.Ptr, muscle.name);
							float seizureMultiplier = modifiers.Item1;
							float seizureAngleOffset = modifiers.Item2;
							Quaternion target = currentPose * Quaternion.Slerp(Quaternion.identity, offset, strength);
							target *= Quaternion.Euler(seizureAngleOffset, 0f, 0f);
							joint.targetRotation = target;
							float legFactor = (isLeg ? 1.5f : 0.7f);
							float absoluteMaxForce = (isLeg ? Mathf.Lerp(20f, 400f, strength) : Mathf.Lerp(15f, 200f, strength));
							float finalStrength = strength * legFactor * seizureMultiplier;
							PhysicsHelper.SetJointDrive(joint, 2300f * finalStrength, 800f * finalStrength, absoluteMaxForce);
							muscle.props.muscleWeight = finalStrength;
						}
					}
					e += Time.deltaTime;
					yield return null;
					bindPose = null;
				}
			}
			finally
			{
				if ((Object)(object)ctx.Puppet != (Object)null && (Object)(object)ctx.Root != (Object)null)
				{
					PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
				}
			}
		}

		private static IEnumerator ForwardBuckle(PuppetMaster puppet)
		{
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
			if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var _))
			{
				PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
			}
			if (!ctx.IsValid())
			{
				yield break;
			}
			Rigidbody chestRb = null;
			foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
			{
				if (m != null && m.name.ToLower().Contains("chest"))
				{
					chestRb = ((Component)m.transform).GetComponent<Rigidbody>();
					break;
				}
			}
			if ((Object)(object)chestRb != (Object)null)
			{
				Vector3 forwardDir = -((Component)chestRb).transform.right;
				chestRb.AddForce(forwardDir * 5.5f, (ForceMode)2);
			}
			float fallDuration = Random.Range(1f, 1.3f);
			float e1 = 0f;
			try
			{
				while (e1 < fallDuration && ctx.IsValid())
				{
					ModuleC_Seizures.Tick(ctx.Ptr);
					float bendProgress = Mathf.Clamp01(e1 / 0.45f);
					float easeBend = bendProgress * bendProgress;
					float currentSpring = Mathf.Lerp(900f, 20f, bendProgress);
					float currentDamping = Mathf.Lerp(150f, 5f, bendProgress);
					float muscleWeight = Mathf.Lerp(0.85f, 0.05f, bendProgress);
					foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (muscle == null)
						{
							continue;
						}
						string name = muscle.name.ToLower();
						ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
						if ((Object)(object)joint == (Object)null)
						{
							continue;
						}
						var (seizureMultiplier, seizureAngleOffset) = ModuleC_Seizures.GetModifiers(ctx.Ptr, muscle.name);
						_ = Quaternion.identity;
						Quaternion targetOffset;
						if (name.Contains("spine"))
						{
							targetOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(-75f, 0f, 0f), easeBend);
						}
						else if (name.Contains("chest"))
						{
							targetOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(-60f, 0f, 0f), easeBend);
						}
						else
						{
							if (!name.Contains("hip"))
							{
								if (name.Contains("knee"))
								{
									float kneeSpring = ((e1 < 0.35f) ? 400f : currentSpring);
									PhysicsHelper.SetJointDrive(joint, kneeSpring * seizureMultiplier, currentDamping, kneeSpring * seizureMultiplier);
									muscle.props.muscleWeight = ((e1 < 0.35f) ? 0.9f : muscleWeight) * seizureMultiplier;
								}
								continue;
							}
							targetOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(150f, 0f, 0f), easeBend);
						}
						joint.targetRotation = targetOffset * Quaternion.Euler(seizureAngleOffset, 0f, 0f);
						PhysicsHelper.SetJointDrive(joint, currentSpring * seizureMultiplier, currentDamping, currentSpring * seizureMultiplier);
						muscle.props.muscleWeight = muscleWeight * seizureMultiplier;
					}
					e1 += Time.deltaTime;
					yield return null;
				}
			}
			finally
			{
				PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
			}
		}

		private static IEnumerator FlaccidParalysis(PuppetMaster puppet)
		{
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
			if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var localRotations))
			{
				localRotations = PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
			}
			float jerkDuration = Random.Range(0.02f, 0.05f);
			float jerkStrength = Random.Range(0.8f, 1.5f);
			Dictionary<string, Quaternion> currentPoseBeforeJerk = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, localRotations);
			MelonCoroutines.Start(SuppressHitReaction(ctx.Puppet));
			Dictionary<string, Quaternion> jerkOffsets = new Dictionary<string, Quaternion>();
			foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
			{
				if (muscle != null)
				{
					Vector3 randEuler = new Vector3(Random.Range(-40f, 40f), Random.Range(-50f, 50f), Random.Range(-30f, 30f));
					Quaternion cp;
					Quaternion basePose = (currentPoseBeforeJerk.TryGetValue(muscle.name, out cp) ? cp : Quaternion.identity);
					jerkOffsets[muscle.name] = basePose * Quaternion.Euler(randEuler);
				}
			}
			ApplyImpactImpulse(ctx.Puppet);
			float e0 = 0f;
			try
			{
				while (e0 < jerkDuration)
				{
					if (!ctx.IsValid())
					{
						yield break;
					}
					float t = Mathf.Clamp01(e0 / jerkDuration);
					foreach (Muscle muscle2 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (muscle2 != null)
						{
							ConfigurableJoint joint = ((Component)muscle2.transform).GetComponent<ConfigurableJoint>();
							if (!((Object)(object)joint == (Object)null) && jerkOffsets.TryGetValue(muscle2.name, out var offset) && currentPoseBeforeJerk.TryGetValue(muscle2.name, out var basePose2))
							{
								joint.targetRotation = Quaternion.Slerp(basePose2, offset, t);
								PhysicsHelper.SetJointDrive(joint, 2500f * jerkStrength, 400f * jerkStrength, 60f);
								muscle2.props.muscleWeight = jerkStrength;
							}
						}
					}
					e0 += Time.deltaTime;
					yield return null;
				}
				if (!ctx.IsValid())
				{
					yield break;
				}
				float fallTime = Random.Range(0.8f, 1.2f);
				float fallStrengthTorso = 0.2f;
				float fallStrengthLegs = 0f;
				float e1 = 0f;
				while (e1 < fallTime)
				{
					if (!ctx.IsValid())
					{
						yield break;
					}
					float localT = e1 / fallTime;
					foreach (Muscle muscle3 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (muscle3 != null)
						{
							string name = muscle3.name.ToLower();
							ConfigurableJoint joint2 = ((Component)muscle3.transform).GetComponent<ConfigurableJoint>();
							if (!((Object)(object)joint2 == (Object)null))
							{
								bool isLeg = name.Contains("knee") || name.Contains("ankle") || name.Contains("hip");
								float baseStrength = (isLeg ? fallStrengthLegs : fallStrengthTorso);
								float currentStrength = Mathf.Lerp(baseStrength, baseStrength * 0.3f, localT);
								float absoluteMaxForce = (isLeg ? 2f : 20f);
								PhysicsHelper.SetJointDrive(joint2, 300f * currentStrength, 100f * currentStrength, absoluteMaxForce);
								muscle3.props.muscleWeight = currentStrength;
							}
						}
					}
					e1 += Time.deltaTime;
					yield return null;
				}
				if (!ctx.IsValid())
				{
					yield break;
				}
				Dictionary<string, Quaternion> frozenTargets = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, localRotations);
				float freezeTime = 0.4f;
				float legDecay = 4f;
				float torsoDecay = 8f;
				float e2 = 0f;
				float totalDuration = freezeTime + torsoDecay;
				float rampIn = 0.1f;
				while (e2 < totalDuration && ctx.IsValid())
				{
					ModuleC_Seizures.Tick(ctx.Ptr);
					foreach (Muscle muscle4 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (muscle4 == null)
						{
							continue;
						}
						string name2 = muscle4.name.ToLower();
						ConfigurableJoint joint3 = ((Component)muscle4.transform).GetComponent<ConfigurableJoint>();
						if (!((Object)(object)joint3 == (Object)null))
						{
							bool isLeg2 = name2.Contains("knee") || name2.Contains("ankle") || name2.Contains("hip");
							float decayDuration = (isLeg2 ? legDecay : torsoDecay);
							float localElapsed = Mathf.Max(0f, e2 - freezeTime);
							float strength = ((e2 < freezeTime) ? Mathf.Clamp01(e2 / rampIn) : Mathf.Clamp01(1f - localElapsed / decayDuration));
							var (seizureMultiplier, seizureAngleOffset) = ModuleC_Seizures.GetModifiers(ctx.Ptr, muscle4.name);
							if (frozenTargets.TryGetValue(muscle4.name, out var frozenTarget))
							{
								joint3.targetRotation = frozenTarget * Quaternion.Euler(seizureAngleOffset, 0f, 0f);
							}
							float absoluteMaxForce2 = (isLeg2 ? 40f : 25f);
							float legFactor = (isLeg2 ? 0.35f : 0.45f);
							float finalStrength = strength * legFactor * seizureMultiplier;
							PhysicsHelper.SetJointDrive(joint3, 300f * finalStrength, 300f * finalStrength, absoluteMaxForce2);
						}
					}
					e2 += Time.deltaTime;
					yield return null;
				}
			}
			finally
			{
				PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
			}
		}

		private static IEnumerator Collapse(PuppetMaster puppet)
		{
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
			MelonCoroutines.Start(SuppressHitReaction(ctx.Puppet));
			if (!ctx.IsValid())
			{
				yield break;
			}
			foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
			{
				if (muscle != null)
				{
					muscle.name.ToLower();
					ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
					if (!((Object)(object)joint == (Object)null))
					{
						PhysicsHelper.SetJointDrive(joint, 0f, 0f, 0f);
						muscle.props.muscleWeight = 0f;
					}
				}
			}
			PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
		}

		private static IEnumerator Fencing(PuppetMaster puppet)
		{
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
			if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var bindPose))
			{
				bindPose = PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
			}
			float bs = Random.Range(0.25f, 0.35f);
			float d = Random.Range(0.6f, 0.8f);
			float rt = Random.Range(0.8f, 1.5f);
			float e = 0f;
			float suppressWindow = 0.3f;
			bool leftIsExtended = Random.value < 0.5f;
			Quaternion extendedElbow = Quaternion.Euler(-10f, 0f, 0f);
			Quaternion extendedShoulder = Quaternion.Euler(70f, 0f, -30f);
			Quaternion extendedWrist = Quaternion.Euler(-10f, 0f, 0f);
			Quaternion flexedElbow = Quaternion.Euler(110f, 0f, 0f);
			Quaternion flexedShoulder = Quaternion.Euler(20f, 0f, 15f);
			Quaternion flexedWrist = Quaternion.Euler(60f, 0f, 0f);
			try
			{
				while (e < bs + d + rt && ctx.IsValid())
				{
					float progress = PhysicsHelper.GetProgress(e, bs, d, rt);
					float strength = PhysicsHelper.GetStrength(e, bs, d, rt);
					if (e < suppressWindow)
					{
						foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
						{
							if (m == null)
							{
								continue;
							}
							string mName = m.name.ToLower();
							if (!mName.Contains("elbow") && !mName.Contains("shoulder") && !mName.Contains("wrist"))
							{
								Rigidbody rb = ((Component)m.transform).GetComponent<Rigidbody>();
								if (!((Object)(object)rb == (Object)null))
								{
									rb.angularVelocity = Vector3.ClampMagnitude(rb.angularVelocity, 2f);
								}
							}
						}
					}
					Dictionary<string, Quaternion> currentPose = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, bindPose);
					foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (muscle == null)
						{
							continue;
						}
						string name = muscle.name.ToLower();
						ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
						if (!((Object)(object)joint == (Object)null) && currentPose.TryGetValue(muscle.name, out var basePose))
						{
							bool thisArmExtended = (name.Contains("_l") ? leftIsExtended : (!leftIsExtended));
							Quaternion offset = Quaternion.identity;
							bool matched = true;
							if (name.Contains("elbow"))
							{
								offset = (thisArmExtended ? extendedElbow : flexedElbow);
							}
							else if (name.Contains("shoulder"))
							{
								offset = (thisArmExtended ? extendedShoulder : flexedShoulder);
							}
							else if (name.Contains("wrist"))
							{
								offset = (thisArmExtended ? extendedWrist : flexedWrist);
							}
							else
							{
								matched = false;
							}
							if (matched)
							{
								Quaternion target = basePose * Quaternion.Slerp(Quaternion.identity, offset, progress);
								joint.targetRotation = target;
								PhysicsHelper.SetJointDrive(joint, 2300f * strength, 700f * strength, 900f * strength);
								muscle.props.muscleWeight = strength;
							}
						}
					}
					e += Time.deltaTime;
					yield return null;
				}
			}
			finally
			{
				PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
			}
		}

		private static void ApplyImpactImpulse(PuppetMaster puppet)
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			ReactionContext reactionContext = new ReactionContext(puppet);
			if (!reactionContext.IsValid())
			{
				return;
			}
			Rigidbody val = null;
			Rigidbody val2 = null;
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)reactionContext.Puppet.muscles)
			{
				if (item != null)
				{
					string text = item.name.ToLower();
					if (text.Contains("head"))
					{
						val = ((Component)item.transform).GetComponent<Rigidbody>();
					}
					if (text.Contains("chest"))
					{
						val2 = ((Component)item.transform).GetComponent<Rigidbody>();
					}
				}
			}
			Vector3 val3 = new Vector3(Random.Range(-1f, 1f), Random.Range(-0.2f, 0.3f), Random.Range(-1f, 1f));
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			float num = Random.Range(5f, 10f);
			if ((Object)(object)val != (Object)null)
			{
				val.AddForce(normalized * num * 0.2f, (ForceMode)1);
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.AddForce(normalized * num, (ForceMode)1);
			}
		}

		private static IEnumerator SuppressHitReaction(PuppetMaster puppet, float duration = 0.3f)
		{
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid())
			{
				yield break;
			}
			float elapsed = 0f;
			float maxReasonableSpin = 2f;
			while (elapsed < duration && ctx.IsValid())
			{
				foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
				{
					if (m != null)
					{
						Rigidbody rb = ((Component)m.transform).GetComponent<Rigidbody>();
						if (!((Object)(object)rb == (Object)null))
						{
							Vector3 av = rb.angularVelocity;
							rb.angularVelocity = Vector3.ClampMagnitude(av, maxReasonableSpin);
						}
					}
				}
				elapsed += Time.fixedDeltaTime;
				yield return (object)new WaitForFixedUpdate();
			}
		}
	}
	internal class ModuleC_Seizures
	{
		public struct SeizureData
		{
			public float intensity;

			public float frequency;

			public float elapsed;

			public float duration;
		}

		private static readonly Dictionary<IntPtr, SeizureData> _active = new Dictionary<IntPtr, SeizureData>();

		public static void Start(IntPtr ptr, float intensity, float duration)
		{
			if (ModClass.SeizuresEnabled)
			{
				_active[ptr] = new SeizureData
				{
					intensity = Mathf.Clamp01(intensity),
					frequency = Mathf.Lerp(3f, 8f, intensity) * 0.8f,
					elapsed = 0f,
					duration = duration
				};
				((MelonBase)ModClass.Instance).LoggerInstance.Msg($"[ModuleC] Seizure start | instensity: {intensity} | duration: {duration}");
			}
		}

		public static void Tick(IntPtr ptr)
		{
			if (_active.TryGetValue(ptr, out var value))
			{
				value.elapsed += Time.deltaTime;
				if (value.elapsed >= value.duration)
				{
					_active.Remove(ptr);
					MelonLogger.Msg("[ModuleC] Seizure ended");
				}
				else
				{
					_active[ptr] = value;
				}
			}
		}

		public static void Stop(IntPtr ptr)
		{
			_active.Remove(ptr);
		}

		public static void Clear(IntPtr ptr)
		{
			_active.Remove(ptr);
		}

		public static bool IsActive(IntPtr ptr)
		{
			return _active.ContainsKey(ptr);
		}

		public static (float strengthMultiplier, float angleOffset) GetModifiers(IntPtr ptr, string muscleName)
		{
			if (!ModClass.SeizuresEnabled)
			{
				return (strengthMultiplier: 1f, angleOffset: 0f);
			}
			if (!_active.TryGetValue(ptr, out var value))
			{
				return (strengthMultiplier: 1f, angleOffset: 0f);
			}
			float num = 1f - Mathf.Clamp01((value.elapsed - value.duration * 0.6f) / (value.duration * 0.4f));
			float num2 = value.intensity * num;
			float num3 = (float)(muscleName.GetHashCode() % 100) * 0.063f;
			float item = 1f + num2 * 2f;
			float item2 = Mathf.Sin(value.elapsed * value.frequency * (float)Math.PI * 2f + num3) * 20f * num2;
			return (strengthMultiplier: item, angleOffset: item2);
		}

		public static void ClearAll()
		{
			_active.Clear();
		}
	}
	internal class ModuleD_Consciousness
	{
		public static IEnumerator Unconscious(PuppetMaster puppet, float duration = 20f)
		{
			ReactionContext ctx = new ReactionContext(puppet);
			if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr))
			{
				yield break;
			}
			BehaviourBaseNav behaviour = null;
			AIBrain brain = null;
			Animator animator = null;
			AIManager manager = null;
			try
			{
				Transform mainTransform = (((Object)(object)ctx.Puppet != (Object)null) ? ((Component)ctx.Puppet).transform : null);
				if ((Object)(object)mainTransform != (Object)null)
				{
					brain = ((Component)mainTransform).GetComponentInParent<AIBrain>();
				}
				if ((Object)(object)brain != (Object)null)
				{
					GameObject brainGO = ((Component)brain).gameObject;
					behaviour = brain.behaviour;
					if ((Object)(object)behaviour == (Object)null)
					{
						behaviour = brainGO.GetComponentInChildren<BehaviourBaseNav>(true);
					}
					animator = brainGO.GetComponentInChildren<Animator>(true);
					manager = brainGO.GetComponentInChildren<AIManager>(true);
				}
				else
				{
					object obj;
					if (!((Object)(object)ctx.Root != (Object)null))
					{
						if (mainTransform == null)
						{
							obj = null;
						}
						else
						{
							Transform root = mainTransform.root;
							obj = ((root != null) ? ((Component)root).gameObject : null);
						}
					}
					else
					{
						obj = ((Component)ctx.Root).gameObject;
					}
					GameObject topRoot = (GameObject)obj;
					if ((Object)(object)topRoot != (Object)null)
					{
						behaviour = topRoot.GetComponentInChildren<BehaviourBaseNav>(true);
						animator = topRoot.GetComponentInChildren<Animator>(true);
						manager = topRoot.GetComponentInChildren<AIManager>(true);
					}
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				((MelonBase)ModClass.Instance).LoggerInstance.Error($"[Unconscious] Exception while fetching components: {ex2}");
			}
			if ((Object)(object)brain != (Object)null)
			{
				((Behaviour)brain).enabled = false;
			}
			if ((Object)(object)animator != (Object)null)
			{
				((Behaviour)animator).enabled = false;
			}
			PhysicsHelper.SaveProfile(ctx.Puppet);
			if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr))
			{
				yield break;
			}
			ctx.Puppet.angularLimitsEnabled = true;
			ctx.Puppet.angularLimits = true;
			ctx.Puppet.animationDisabledbyStates = true;
			ctx.Puppet.mappingWeight = 0f;
			ctx.Puppet.ActivateRagdoll(Object.op_Implicit((Object)(object)manager));
			JointDrive val;
			foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
			{
				if (m != null)
				{
					m.props.muscleWeight = 0f;
					ConfigurableJoint joint = ((Component)m.transform).GetComponent<ConfigurableJoint>();
					if ((Object)(object)joint != (Object)null)
					{
						val = default(JointDrive);
						((JointDrive)(ref val)).positionSpring = 0f;
						((JointDrive)(ref val)).positionDamper = 5f;
						JointDrive drive = (joint.angularXDrive = (joint.slerpDrive = val));
						joint.angularYZDrive = drive;
					}
				}
			}
			((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC unconcious!");
			float elapsedGuard = 0f;
			val = default(JointDrive);
			((JointDrive)(ref val)).positionSpring = 1f;
			((JointDrive)(ref val)).positionDamper = 100400f;
			((JointDrive)(ref val)).maximumForce = 0f;
			JointDrive zeroDrive = val;
			try
			{
				while (elapsedGuard < duration)
				{
					if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr))
					{
						yield break;
					}
					if (!DeathTracker.UnconsciousNPCs.Contains(ctx.Ptr))
					{
						PhysicsHelper.ApplyProfile(ctx.Puppet);
						yield break;
					}
					if ((Object)(object)behaviour != (Object)null)
					{
						behaviour.locoState = (LocoState)5;
					}
					if ((Object)(object)brain != (Object)null && (Object)(object)brain.behaviour != (Object)null)
					{
						brain.behaviour.mentalState = (MentalState)0;
					}
					foreach (Muscle m2 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
					{
						if (m2 != null)
						{
							ConfigurableJoint joint2 = ((Component)m2.transform).GetComponent<ConfigurableJoint>();
							if ((Object)(object)joint2 != (Object)null)
							{
								joint2.slerpDrive = zeroDrive;
								joint2.angularXDrive = zeroDrive;
								joint2.angularYZDrive = zeroDrive;
							}
						}
					}
					elapsedGuard += Time.deltaTime;
					yield return (object)new WaitForFixedUpdate();
				}
				if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr) || (int)ctx.Puppet.state == 1 || !DeathTracker.UnconsciousNPCs.Contains(ctx.Ptr))
				{
					yield break;
				}
				((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC woke up!");
				if ((Object)(object)animator != (Object)null)
				{
					((Behaviour)animator).enabled = true;
				}
				if ((Object)(object)manager != (Object)null)
				{
					((Behaviour)manager).enabled = true;
				}
				if ((Object)(object)brain != (Object)null)
				{
					((Behaviour)brain).enabled = true;
				}
				if ((Object)(object)behaviour != (Object)null)
				{
					behaviour.locoState = (LocoState)3;
				}
				if ((Object)(object)brain != (Object)null && (Object)(object)brain.behaviour != (Object)null)
				{
					brain.behaviour.mentalState = (MentalState)2;
				}
				float recoverTime = 1.5f;
				float elapsed = 0f;
				while (elapsed < recoverTime)
				{
					if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr) || !DeathTracker.UnconsciousNPCs.Contains(ctx.Ptr))
					{
						yield break;
					}
					float t = elapsed / recoverTime;
					ctx.Puppet.mappingWeight = t;
					PhysicsHelper.ApplyProfile(ctx.Puppet, t);
					elapsed += Time.deltaTime;
					yield return null;
				}
				if (ctx.IsValid())
				{
					ctx.Puppet.mappingWeight = 1f;
					PhysicsHelper.ApplyProfile(ctx.Puppet);
				}
			}
			finally
			{
				CleanupTracker(ctx.Ptr);
			}
		}

		private static void CleanupTracker(IntPtr ptr)
		{
			DeathTracker.UnconsciousNPCs.Remove(ptr);
			DeathTracker.UnconsciousStartTime.Remove(ptr);
			DeathTracker.Profiles.Remove(ptr);
		}
	}
	public static class PhysicsHelper
	{
		public static void EnsureBindPoseCached(PuppetMaster puppet)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero || DeathTracker.BindPoseRotations.ContainsKey(((Il2CppObjectBase)puppet).Pointer))
			{
				return;
			}
			Dictionary<string, Quaternion> dictionary = new Dictionary<string, Quaternion>();
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					dictionary[item.name] = item.transform.localRotation;
				}
			}
			DeathTracker.BindPoseRotations[((Il2CppObjectBase)puppet).Pointer] = dictionary;
		}

		public static Dictionary<string, Quaternion> SaveMuscleCurrentPose(PuppetMaster puppet, Dictionary<string, Quaternion> initialLocalRotations)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Quaternion> dictionary = new Dictionary<string, Quaternion>();
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
					if (!((Object)(object)component == (Object)null) && initialLocalRotations.TryGetValue(item.name, out var value))
					{
						dictionary[item.name] = JointSpaceHelper.GetCurrentRelativeRotation(component, value);
					}
				}
			}
			return dictionary;
		}

		public static Dictionary<string, Quaternion> SaveInitialLocalRotations(PuppetMaster puppet)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Quaternion> dictionary = new Dictionary<string, Quaternion>();
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					dictionary[item.name] = item.transform.localRotation;
				}
			}
			return dictionary;
		}

		public static void SetJointDrive(ConfigurableJoint joint, float spring, float damper, float maxForce)
		{
			//IL_0003: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			JointDrive val = default(JointDrive);
			((JointDrive)(ref val)).positionSpring = spring;
			((JointDrive)(ref val)).positionDamper = damper;
			((JointDrive)(ref val)).maximumForce = maxForce;
			JointDrive angularYZDrive = (joint.angularXDrive = (joint.slerpDrive = val));
			joint.angularYZDrive = angularYZDrive;
		}

		public static void ApplyToSpine(PuppetMaster puppet, float progress, float strength, Quaternion spineRot, Quaternion headRot, Quaternion chestRot, Quaternion hipRot)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item == null)
				{
					continue;
				}
				string text = item.name.ToLower();
				ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Quaternion identity = Quaternion.identity;
				if (text.Contains("spine"))
				{
					identity = spineRot;
				}
				else if (text.Contains("chest"))
				{
					identity = chestRot;
				}
				else if (text.Contains("head"))
				{
					identity = headRot;
				}
				else
				{
					if (!text.Contains("hip"))
					{
						continue;
					}
					identity = hipRot;
				}
				component.targetRotation = Quaternion.Slerp(Quaternion.identity, identity, progress);
				SetJointDrive(component, 3000f * strength, 800f * strength, 3000f * strength);
				item.props.muscleWeight = strength;
			}
		}

		public static void ApplyToMuscles(PuppetMaster puppet, float progress, float strength, Quaternion elbowRot, Quaternion wristRot, Quaternion shoulderRot, Quaternion kneeRot, Quaternion ankleRot, string sideFilter = null, bool includeLegs = true, bool includeArms = true)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: 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)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: 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_0144: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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)
			ModuleC_Seizures.Tick(((Il2CppObjectBase)puppet).Pointer);
			foreach (Muscle item3 in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item3 == null)
				{
					continue;
				}
				string text = item3.name.ToLower();
				if (sideFilter != null && !text.Contains(sideFilter))
				{
					continue;
				}
				ConfigurableJoint component = ((Component)item3.transform).GetComponent<ConfigurableJoint>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Quaternion identity = Quaternion.identity;
				bool flag = text.Contains("knee") || text.Contains("ankle") || text.Contains("hip");
				bool flag2 = text.Contains("wrist") || text.Contains("shoulder") || text.Contains("elbow");
				if ((flag && !includeLegs) || (flag2 && !includeArms))
				{
					continue;
				}
				if (text.Contains("elbow"))
				{
					identity = elbowRot;
				}
				else if (text.Contains("wrist"))
				{
					identity = wristRot;
				}
				else if (text.Contains("shoulder"))
				{
					identity = shoulderRot;
				}
				else if (text.Contains("knee"))
				{
					identity = kneeRot;
				}
				else
				{
					if (!text.Contains("ankle"))
					{
						continue;
					}
					identity = ankleRot;
				}
				(float strengthMultiplier, float angleOffset) modifiers = ModuleC_Seizures.GetModifiers(((Il2CppObjectBase)puppet).Pointer, item3.name);
				float item = modifiers.strengthMultiplier;
				float item2 = modifiers.angleOffset;
				Quaternion val = Quaternion.Slerp(Quaternion.identity, identity, progress);
				val *= Quaternion.Euler(item2, 0f, 0f);
				component.targetRotation = val;
				float num = strength * item;
				float num2 = (flag ? 0.35f : 1f);
				SetJointDrive(component, 3000f * num, 800f * num * num2, 3000f * num * num2);
				item3.props.muscleWeight = num;
			}
		}

		public static float GetProgress(float e, float bs, float d, float rt)
		{
			return (e < bs) ? Mathf.Clamp01(e / bs) : 1f;
		}

		public static float GetStrength(float e, float bs, float d, float rt)
		{
			if (e < bs)
			{
				return Mathf.Clamp01(e / bs);
			}
			if (e < bs + d)
			{
				return 1f;
			}
			return 1f - Mathf.Clamp01((e - bs - d) / rt);
		}

		public static void RestoreAndResetJoints(PuppetMaster puppet, Dictionary<string, float> originalWeights)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero)
			{
				return;
			}
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					if (originalWeights.TryGetValue(item.name, out var value))
					{
						item.props.muscleWeight = value;
					}
					ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
					if (!((Object)(object)component == (Object)null))
					{
						SetJointDrive(component, 0f, 0f, 0f);
						component.targetRotation = Quaternion.identity;
					}
				}
			}
		}

		public static Dictionary<string, float> SaveMuscleWeights(PuppetMaster puppet)
		{
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					dictionary[item.name] = item.props.muscleWeight;
				}
			}
			return dictionary;
		}

		public static void SaveProfile(PuppetMaster puppet)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero)
			{
				return;
			}
			NPCMuscleProfile nPCMuscleProfile = new NPCMuscleProfile();
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					nPCMuscleProfile.MaxForces[item.name] = item._maxForce;
					nPCMuscleProfile.MuscleWeights[item.name] = item.props.muscleWeight;
					nPCMuscleProfile.MuscleDampers[item.name] = item.props.muscleDamper;
					ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
					if ((Object)(object)component != (Object)null)
					{
						nPCMuscleProfile.Drives[item.name] = component.slerpDrive;
					}
				}
			}
			DeathTracker.Profiles[((Il2CppObjectBase)puppet).Pointer] = nPCMuscleProfile;
		}

		public static void ApplyProfile(PuppetMaster puppet, float t = 1f)
		{
			//IL_0152: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero || !DeathTracker.Profiles.TryGetValue(((Il2CppObjectBase)puppet).Pointer, out var value))
			{
				return;
			}
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item == null)
				{
					continue;
				}
				if (value.MaxForces.TryGetValue(item.name, out var value2))
				{
					item._maxForce = Mathf.Lerp(0f, value2, t);
				}
				if (value.MuscleWeights.TryGetValue(item.name, out var value3))
				{
					item.props.muscleWeight = Mathf.Lerp(0f, value3, t);
				}
				if (value.MuscleDampers.TryGetValue(item.name, out var value4))
				{
					item.props.muscleDamper = Mathf.Lerp(0f, value4, t);
				}
				if (t >= 1f)
				{
					ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
					if ((Object)(object)component != (Object)null && value.Drives.TryGetValue(item.name, out var value5))
					{
						component.slerpDrive = value5;
						component.angularXDrive = value5;
						component.angularYZDrive = value5;
					}
				}
			}
		}

		public static void ResetProfile(PuppetMaster puppet)
		{
			if (!DeathTracker.Profiles.TryGetValue(((Il2CppObjectBase)puppet).Pointer, out var value))
			{
				return;
			}
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					if (value.MaxForces.TryGetValue(item.name, out var value2))
					{
						item._maxForce = value2;
					}
					if (value.MuscleWeights.TryGetValue(item.name, out var value3))
					{
						item.props.muscleWeight = value3;
					}
					if (value.MuscleDampers.TryGetValue(item.name, out var value4))
					{
						item.props.muscleDamper = value4;
					}
				}
			}
		}

		public static string ShowStats(PuppetMaster puppet)
		{
			//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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero)
			{
				return "Puppet NULL";
			}
			float value = -1f;
			float value2 = -1f;
			float mappingWeight = puppet.mappingWeight;
			float value3 = -1f;
			float value4 = -1f;
			float value5 = -1f;
			foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
			{
				if (item != null)
				{
					value = item.props.muscleWeight;
					value2 = item.props.muscleDamper;
					value3 = item._maxForce;
					ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
					if ((Object)(object)component != (Object)null)
					{
						JointDrive slerpDrive = component.slerpDrive;
						value4 = ((JointDrive)(ref slerpDrive)).positionSpring;
						slerpDrive = component.slerpDrive;
						value5 = ((JointDrive)(ref slerpDrive)).positionDamper;
					}
					break;
				}
			}
			return $"[Diag] mWeight={value}, mDamper={value2}, maxForce={value3} | mapWeight={mappingWeight}, DriveSpring={value4}, DriveDamper={value5}";
		}
	}
}
namespace InjuriesMod.Core
{
	public class NPCMuscleProfile
	{
		public Dictionary<string, float> MaxForces = new Dictionary<string, float>();

		public Dictionary<string, float> MuscleWeights = new Dictionary<string, float>();

		public Dictionary<string, float> MuscleDampers = new Dictionary<string, float>();

		public Dictionary<string, JointDrive> Drives = new Dictionary<string, JointDrive>();
	}
	public static class DeathTracker
	{
		public static Dictionary<IntPtr, NPCMuscleProfile> Profiles = new Dictionary<IntPtr, NPCMuscleProfile>();

		public static Dictionary<IntPtr, int> PointerGeneration = new Dictionary<IntPtr, int>();

		public static Dictionary<IntPtr, int> LastRegisteredFrame = new Dictionary<IntPtr, int>();

		public static HashSet<IntPtr> AlreadyDead = new HashSet<IntPtr>();

		public static HashSet<IntPtr> UnconsciousNPCs = new HashSet<IntPtr>();

		public static Dictionary<IntPtr, float> UnconsciousStartTime = new Dictionary<IntPtr, float>();

		public static Dictionary<IntPtr, string> LastHitBone = new Dictionary<IntPtr, string>();

		public static Dictionary<IntPtr, string> PriorityDeathCause = new Dictionary<IntPtr, string>();

		public static Dictionary<IntPtr, AttackType> LastAttackType = new Dictionary<IntPtr, AttackType>();

		public static Dictionary<IntPtr, float> LastAttackDamage = new Dictionary<IntPtr, float>();

		public static Dictionary<IntPtr, Dictionary<string, Quaternion>> BindPoseRotations = new Dictionary<IntPtr, Dictionary<string, Quaternion>>();

		public static Random Rng = new Random();

		public static bool TryRegisterSpawn(IntPtr ptr, out int currentGeneration)
		{
			currentGeneration = -1;
			if (ptr == IntPtr.Zero)
			{
				return false;
			}
			int frameCount = Time.frameCount;
			if (LastRegisteredFrame.TryGetValue(ptr, out var value) && value == frameCount)
			{
				currentGeneration = ((!PointerGeneration.TryGetValue(ptr, out var value2)) ? 1 : value2);
				return false;
			}
			LastRegisteredFrame[ptr] = frameCount;
			if (PointerGeneration.TryGetValue(ptr, out var value3))
			{
				currentGeneration = value3 + 1;
			}
			else
			{
				currentGeneration = 1;
			}
			PointerGeneration[ptr] = currentGeneration;
			return true;
		}

		public static void ClearNPC(IntPtr ptr)
		{
			if (!(ptr == IntPtr.Zero) && (AlreadyDead.Contains(ptr) || LastHitBone.ContainsKey(ptr) || UnconsciousNPCs.Contains(ptr) || LastAttackType.ContainsKey(ptr) || BindPoseRotations.ContainsKey(ptr) || Profiles.ContainsKey(ptr)))
			{
				((MelonBase)ModClass.Instance).LoggerInstance.Msg($"Clearing NPC data (ptr: {ptr})");
				ModuleC_Seizures.Clear(ptr);
				AlreadyDead.Remove(ptr);
				UnconsciousNPCs.Remove(ptr);
				UnconsciousStartTime.Remove(ptr);
				LastHitBone.Remove(ptr);
				PriorityDeathCause.Remove(ptr);
				LastAttackType.Remove(ptr);
				LastAttackDamage.Remove(ptr);
				BindPoseRotations.Remove(ptr);
				Profiles.Remove(ptr);
			}
		}

		public static void ClearAll()
		{
			AlreadyDead.Clear();
			UnconsciousNPCs.Clear();
			UnconsciousStartTime.Clear();
			LastHitBone.Clear();
			PriorityDeathCause.Clear();
			LastAttackType.Clear();
			LastAttackDamage.Clear();
			BindPoseRotations.Clear();
			Profiles.Clear();
		}
	}
	public class ModClass : MelonMod
	{
		public enum FrequencyScale
		{
			None,
			Rare,
			Default,
			Common,
			Always
		}

		public static ModClass Instance;

		public static bool UnconsciousEnabled = true;

		public static bool BrainInjuriesEnabled = true;

		public static bool TorsoArmorEnabled = true;

		public static bool HeadBluntResistEnabled = true;

		public static bool SeizuresEnabled = true;

		public static float SeizureChanceBlunt = 20f;

		public static float SeizureChancePiercing = 8f;

		public static Dictionary<ModuleA_Impact.ImmediateReaction, FrequencyScale> UserSettings = new Dictionary<ModuleA_Impact.ImmediateReaction, FrequencyScale>
		{
			{
				ModuleA_Impact.ImmediateReaction.FlaccidParalysis,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.ImmediateReaction.Posturing,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.ImmediateReaction.ForwardBuckle,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.ImmediateReaction.Fencing,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.ImmediateReaction.None,
				FrequencyScale.Default
			}
		};

		public static Dictionary<ModuleA_Impact.PostureTendency, FrequencyScale> PosturingSettings = new Dictionary<ModuleA_Impact.PostureTendency, FrequencyScale>
		{
			{
				ModuleA_Impact.PostureTendency.Flexor,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.PostureTendency.Extensor,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.PostureTendency.Mixed,
				FrequencyScale.Default
			},
			{
				ModuleA_Impact.PostureTendency.None,
				FrequencyScale.Default
			}
		};

		public override void OnInitializeMelon()
		{
			Harmony.CreateAndPatchAll(typeof(ModClass).Assembly, (string)null);
			SetupBoneMenu();
			Instance = this;
			((MelonBase)this).LoggerInstance.Msg("Mod loaded!");
		}

		public static float GetMultiplier(FrequencyScale scale)
		{
			if (1 == 0)
			{
			}
			float result = scale switch
			{
				FrequencyScale.None => 0f, 
				FrequencyScale.Rare => 0.5f, 
				FrequencyScale.Default => 1f, 
				FrequencyScale.Common => 2f, 
				FrequencyScale.Always => 10f, 
				_ => 1f, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static void SetupBoneMenu()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: 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_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(1f, 0.988f, 0.729f);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(1f, 0.25f, 0.25f);
			Page val3 = Page.Root.CreatePage("Brain Injuries", val2, 0, true);
			Page val4 = val3.CreatePage("GENERAL SETTINGS", val, 0, true);
			val4.CreateBool("Knockouts / Unconscious", Color.cyan, true, (Action<bool>)delegate(bool v)
			{
				UnconsciousEnabled = v;
			});
			val4.CreateBool("Brain Injuries", Color.yellow, true, (Action<bool>)delegate(bool v)
			{
				BrainInjuriesEnabled = v;
			});
			val4.CreateBool("Seizures", Color.yellow, true, (Action<bool>)delegate(bool v)
			{
				SeizuresEnabled = v;
				if (!v)
				{
					ModuleC_Seizures.ClearAll();
				}
			});
			Page val5 = val3.CreatePage("SEIZURE CHANCE", val, 0, true);
			val5.CreateFloat("Blunt Seizure Chance %", Color.white, SeizureChanceBlunt, 1f, 0f, 100f, (Action<float>)delegate(float v)
			{
				SeizureChanceBlunt = v;
			});
			val5.CreateFloat("Piercing Seizure Chance %", Color.white, SeizureChancePiercing, 1f, 0f, 100f, (Action<float>)delegate(float v)
			{
				SeizureChancePiercing = v;
			});
			Page val6 = val3.CreatePage("DAMAGE RESISTANCE", val, 0, true);
			val6.CreateBool("Reduced Torso Damage", Color.white, true, (Action<bool>)delegate(bool v)
			{
				TorsoArmorEnabled = v;
			});
			val6.CreateBool("Reduced Blunt Head Damage", Color.white, true, (Action<bool>)delegate(bool v)
			{
				HeadBluntResistEnabled = v;
			});
			Page val7 = val3.CreatePage("REACTION WEIGHTS", Color.yellow, 0, true);
			Page val8 = val7.CreatePage("IMMEDIATE REACTIONS", Color.white, 0, true);
			Page val9 = val7.CreatePage("POSTURING TYPES", Color.white, 0, true);
			foreach (ModuleA_Impact.ImmediateReaction reaction in UserSettings.Keys.ToList())
			{
				val8.CreateEnum(reaction.ToString(), Color.white, (Enum)UserSettings[reaction], (Action<Enum>)delegate(Enum obj)
				{
					UserSettings[reaction] = (FrequencyScale)(object)obj;
				});
			}
			foreach (ModuleA_Impact.PostureTendency reaction2 in PosturingSettings.Keys.ToList())
			{
				val9.CreateEnum(reaction2.ToString(), Color.white, (Enum)PosturingSettings[reaction2], (Action<Enum>)delegate(Enum obj)
				{
					PosturingSettings[reaction2] = (FrequencyScale)(object)obj;
				});
			}
			val7.CreateFunction("RESTORE TO DEFAULT", Color.blue, (Action)delegate
			{
				foreach (ModuleA_Impact.ImmediateReaction item in UserSettings.Keys.ToList())
				{
					UserSettings[item] = FrequencyScale.Default;
				}
				foreach (ModuleA_Impact.PostureTendency item2 in PosturingSettings.Keys.ToList())
				{
					PosturingSettings[item2] = FrequencyScale.Default;
				}
				SeizureChanceBlunt = 20f;
				SeizureChancePiercing = 8f;
				MelonLogger.Msg("Restored settings (buttons will still show old values)");
			});
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			DeathTracker.ClearAll();
			((MelonBase)this).LoggerInstance.Msg("Scene cleared.");
		}
	}
	public class ReactionContext
	{
		public readonly IntPtr Ptr;

		public readonly int Generation;

		public readonly Transform Root;

		public readonly PuppetMaster Puppet;

		public ReactionContext(PuppetMaster puppet)
		{
			Puppet = puppet;
			Ptr = (((Object)(object)puppet != (Object)null) ? ((Il2CppObjectBase)puppet).Pointer : IntPtr.Zero);
			Root = (((Object)(object)puppet != (Object)null) ? ((Component)puppet).transform : null);
			if (Ptr != IntPtr.Zero && DeathTracker.PointerGeneration.TryGetValue(Ptr, out var value))
			{
				Generation = value;
			}
			else
			{
				Generation = -1;
			}
		}

		public bool IsValid()
		{
			if ((Object)(object)Root == (Object)null || Ptr == IntPtr.Zero || Generation < 0)
			{
				return false;
			}
			int value;
			return DeathTracker.PointerGeneration.TryGetValue(Ptr, out value) && value == Generation;
		}
	}
}