Decompiled source of RepoLimbMod v0.2.1

RepoLimbMod.dll

Decompiled 13 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RepoLimbMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyInformationalVersion("0.2.1")]
[assembly: AssemblyProduct("RepoLimbMod")]
[assembly: AssemblyTitle("RepoLimbMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.1.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 RepoLimbMod
{
	internal sealed class BodyParts
	{
		internal const int Torso = 0;

		internal const int Count = 5;

		internal readonly Transform[] Roots = (Transform[])(object)new Transform[5];

		internal readonly List<Renderer>[] Renderers = new List<Renderer>[5];

		internal static Limb ToLimb(int index)
		{
			return index switch
			{
				1 => Limb.LeftArm, 
				2 => Limb.RightArm, 
				3 => Limb.LeftLeg, 
				4 => Limb.RightLeg, 
				_ => Limb.None, 
			};
		}

		internal static int ToIndex(Limb limb)
		{
			return limb switch
			{
				Limb.LeftArm => 1, 
				Limb.RightArm => 2, 
				Limb.LeftLeg => 3, 
				Limb.RightLeg => 4, 
				_ => 0, 
			};
		}

		internal static BodyParts Collect(PlayerAvatarVisuals visuals)
		{
			BodyParts bodyParts = new BodyParts();
			Transform[] componentsInChildren = ((Component)visuals).GetComponentsInChildren<Transform>(true);
			Transform val = (((Object)(object)visuals.playerAvatarRightArm != (Object)null) ? visuals.playerAvatarRightArm.rightArmTransform : null);
			Transform val2 = Find(componentsInChildren, "ANIM HEAD BOT");
			bodyParts.Roots[0] = Find(componentsInChildren, "ANIM BODY BOT");
			bodyParts.Roots[1] = Find(componentsInChildren, "ANIM ARM L");
			bodyParts.Roots[2] = (((Object)(object)val != (Object)null) ? val : Find(componentsInChildren, "ANIM ARM R"));
			bodyParts.Roots[3] = Find(componentsInChildren, "ANIM LEG L BOT") ?? Find(componentsInChildren, "ANIM LEG L TOP");
			bodyParts.Roots[4] = Find(componentsInChildren, "ANIM LEG R BOT") ?? Find(componentsInChildren, "ANIM LEG R TOP");
			Transform val3 = (((Object)(object)visuals.playerAvatarRightArm != (Object)null) ? visuals.playerAvatarRightArm.grabberTransform : null);
			for (int i = 0; i < 5; i++)
			{
				List<Renderer> list = new List<Renderer>();
				Transform val4 = bodyParts.Roots[i];
				if ((Object)(object)val4 == (Object)null)
				{
					Plugin.Log.LogWarning((object)$"Hittade ingen transform för kroppsdel {i}.");
					bodyParts.Renderers[i] = list;
					continue;
				}
				Renderer[] componentsInChildren2 = ((Component)val4).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val5 in componentsInChildren2)
				{
					if ((val5 is MeshRenderer || val5 is SkinnedMeshRenderer) && (!((Object)(object)val3 != (Object)null) || !((Component)val5).transform.IsChildOf(val3)) && UnderCosmeticParent(((Component)val5).transform, val4) && (i != 0 || (!UnderAny(((Component)val5).transform, bodyParts.Roots, 1) && (!((Object)(object)val2 != (Object)null) || !((Component)val5).transform.IsChildOf(val2)))))
					{
						list.Add(val5);
					}
				}
				bodyParts.Renderers[i] = list;
			}
			return bodyParts;
		}

		internal Vector3 Center(int index)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			List<Renderer> list = Renderers[index];
			if (list.Count == 0)
			{
				if (!((Object)(object)Roots[index] != (Object)null))
				{
					return Vector3.zero;
				}
				return Roots[index].position;
			}
			Vector3 val = Vector3.zero;
			foreach (Renderer item in list)
			{
				val += ((Component)item).transform.position;
			}
			return val / (float)list.Count;
		}

		private static bool UnderAny(Transform t, Transform[] roots, int from)
		{
			for (int i = from; i < roots.Length; i++)
			{
				if ((Object)(object)roots[i] != (Object)null && t.IsChildOf(roots[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static bool UnderCosmeticParent(Transform t, Transform root)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				if (((Object)val).name.StartsWith("Cosmetic Parent"))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static Transform Find(Transform[] all, string name)
		{
			foreach (Transform val in all)
			{
				if (((Object)val).name == name)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal sealed class LimbConfig
	{
		internal readonly ConfigEntry<float> MinDamagePercent;

		internal readonly ConfigEntry<float> ArmZoneHeight;

		internal readonly ConfigEntry<float> OneLegSpeed;

		internal readonly ConfigEntry<float> OneLegJump;

		internal readonly ConfigEntry<float> NoLegsSpeed;

		internal readonly ConfigEntry<float> OneArmGrabStrength;

		internal readonly ConfigEntry<bool> OneArmBlocksRotate;

		internal readonly ConfigEntry<bool> DumpHierarchy;

		internal LimbConfig(ConfigFile cfg)
		{
			MinDamagePercent = cfg.Bind<float>("Trigger", "MinDamagePercent", 0.2f, "Andel av maxhälsan (0-1) som en enskild träff måste ta för att lemmen i träffzonen ska förloras.");
			ArmZoneHeight = cfg.Bind<float>("Trigger", "ArmZoneHeight", 0.5f, "Relativ höjd på kroppen (0 = fötter, 1 = topp) där armzonen börjar. Under = ben.");
			OneLegSpeed = cfg.Bind<float>("Legs", "OneLegSpeed", 0.6f, "Hastighetsmultiplikator med ett ben. Sprint är avstängd.");
			OneLegJump = cfg.Bind<float>("Legs", "OneLegJump", 0.6f, "Hoppkraftsmultiplikator med ett ben.");
			NoLegsSpeed = cfg.Bind<float>("Legs", "NoLegsSpeed", 0.6f, "Hastighetsmultiplikator utan ben (utöver tvingad crouch). Hopp och sprint är avstängda.");
			OneArmGrabStrength = cfg.Bind<float>("Arms", "OneArmGrabStrength", 0.5f, "Greppstyrkemultiplikator med en arm. Utan armar kan inget greppas.");
			OneArmBlocksRotate = cfg.Bind<bool>("Arms", "OneArmBlocksRotate", true, "Om rotation av greppade objekt är avstängd med en arm.");
			DumpHierarchy = cfg.Bind<bool>("Debug", "DumpHierarchy", false, "Skriver spelarmodellens hierarki till loggen (för att hitta lemmar till visuell fas).");
		}
	}
	internal static class LimbNetwork
	{
		private const byte EventCode = 151;

		private static bool registered;

		internal static void EnsureRegistered()
		{
			if (!registered && PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
				registered = true;
			}
		}

		internal static void Broadcast()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0034: Expected O, but got Unknown
			if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom)
			{
				PhotonNetwork.RaiseEvent((byte)151, (object)(int)LimbState.Local, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
		}

		private static void OnEvent(EventData e)
		{
			if (e.Code == 151 && e.CustomData is int lost)
			{
				LimbState.SetRemote(e.Sender, (Limb)lost);
			}
		}
	}
	internal sealed class LimbPart : MonoBehaviour
	{
		internal static readonly List<LimbPart> All = new List<LimbPart>();

		private static readonly int HurtAmount = Shader.PropertyToID("_ColorOverlayAmount");

		internal int OwnerViewID = -1;

		internal int Index = -1;

		internal PlayerAvatar Owner;

		internal PhysGrabObject Grab;

		internal bool Active;

		private PhotonView view;

		private bool visualsBuilt;

		internal Limb Limb => BodyParts.ToLimb(Index);

		private void Awake()
		{
			Grab = ((Component)this).GetComponent<PhysGrabObject>();
			view = ((Component)this).GetComponent<PhotonView>();
			All.Add(this);
			PhysGrabObjectImpactDetector component = ((Component)this).GetComponent<PhysGrabObjectImpactDetector>();
			if ((Object)(object)component != (Object)null)
			{
				component.destroyDisable = true;
			}
			object[] array = (((Object)(object)view != (Object)null) ? view.InstantiationData : null);
			if (array != null && array.Length == 2 && array[0] is int ownerViewID && array[1] is int index)
			{
				Init(ownerViewID, index);
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
		}

		internal void Init(int ownerViewID, int index)
		{
			//IL_007d: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			OwnerViewID = ownerViewID;
			Index = index;
			((Object)this).name = $"RepoLimbMod Part {index} ({ownerViewID})";
			BoxCollider componentInChildren = ((Component)this).GetComponentInChildren<BoxCollider>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.size = ((index == 0) ? new Vector3(0.45f, 0.5f, 0.35f) : ((index <= 2) ? new Vector3(0.15f, 0.4f, 0.15f) : new Vector3(0.18f, 0.45f, 0.18f)));
			}
		}

		private void Update()
		{
			if ((Object)(object)Owner == (Object)null && OwnerViewID > 0)
			{
				PhotonView val = PhotonView.Find(OwnerViewID);
				Owner = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PlayerAvatar>() : null);
			}
			if (!visualsBuilt && (Object)(object)Owner != (Object)null)
			{
				BuildVisuals();
			}
			if (!Active && (Object)(object)Grab != (Object)null && SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated)
			{
				Grab.OverrideDeactivate(0.1f);
			}
		}

		internal void Place(Vector3 position, Quaternion rotation)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Active = true;
			Grab.OverrideDeactivateReset();
			Grab.Teleport(position, rotation);
		}

		internal void Hide()
		{
			Active = false;
			Grab.OverrideDeactivate(0.1f);
		}

		internal void ReleaseLocalGrab()
		{
			if ((Object)(object)Grab == (Object)null)
			{
				return;
			}
			foreach (PhysGrabber item in Grab.playerGrabbing.ToList())
			{
				if ((Object)(object)item != (Object)null && item.isLocal)
				{
					item.ReleaseObject(view.ViewID, 0.25f);
				}
			}
		}

		private void BuildVisuals()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			BodyParts bodyParts = ((Component)Owner).GetComponent<LimbVisuals>()?.Parts;
			if (bodyParts == null || Index < 0 || Index >= 5)
			{
				return;
			}
			visualsBuilt = true;
			Transform val = bodyParts.Roots[Index];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = new GameObject("Visual");
			val2.transform.SetParent(((Component)this).transform, false);
			List<Transform> list = new List<Transform>();
			foreach (Renderer item in bodyParts.Renderers[Index])
			{
				MeshFilter val3 = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent<MeshFilter>() : null);
				if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.sharedMesh == (Object)null))
				{
					GameObject val4 = new GameObject(((Object)item).name);
					val4.transform.SetParent(val2.transform, false);
					val4.transform.localPosition = val.InverseTransformPoint(((Component)item).transform.position);
					val4.transform.localRotation = Quaternion.Inverse(val.rotation) * ((Component)item).transform.rotation;
					val4.transform.localScale = Divide(((Component)item).transform.lossyScale, val.lossyScale);
					val4.AddComponent<MeshFilter>().sharedMesh = val3.sharedMesh;
					((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterials = CopyWithoutHurtFlash(item.sharedMaterials);
					list.Add(val4.transform);
				}
			}
			if (list.Count <= 0)
			{
				return;
			}
			Vector3 val5 = Vector3.zero;
			foreach (Transform item2 in list)
			{
				val5 += item2.localPosition;
			}
			val2.transform.localPosition = -val5 / (float)list.Count;
		}

		private static Material[] CopyWithoutHurtFlash(Material[] source)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			Material[] array = (Material[])(object)new Material[source.Length];
			for (int i = 0; i < source.Length; i++)
			{
				if (!((Object)(object)source[i] == (Object)null))
				{
					array[i] = new Material(source[i]);
					if (array[i].HasProperty(HurtAmount))
					{
						array[i].SetFloat(HurtAmount, 0f);
					}
				}
			}
			return array;
		}

		private static Vector3 Divide(Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0020: 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)
			return new Vector3(a.x / b.x, a.y / b.y, a.z / b.z);
		}
	}
	internal static class LimbParts
	{
		internal static LimbPart Find(PlayerAvatar owner, int index)
		{
			if ((Object)(object)owner == (Object)null)
			{
				return null;
			}
			int viewID = owner.photonView.ViewID;
			foreach (LimbPart item in LimbPart.All)
			{
				if ((Object)(object)item != (Object)null && item.OwnerViewID == viewID && item.Index == index)
				{
					return item;
				}
			}
			return null;
		}

		internal static bool HasParts(PlayerAvatar owner)
		{
			return (Object)(object)Find(owner, 0) != (Object)null;
		}

		internal static void SpawnAll()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !SemiFunc.RunIsLevel() || (Object)(object)LimbPartTemplate.Template == (Object)null)
			{
				return;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!((Object)(object)player == (Object)null) && !HasParts(player))
				{
					for (int i = 0; i < 5; i++)
					{
						LimbPartTemplate.Spawn(player, i);
					}
				}
			}
		}

		internal static void OnStateChanged(PlayerAvatar avatar, Limb before, Limb after)
		{
			if ((Object)(object)avatar == (Object)null)
			{
				return;
			}
			bool flag = SemiFunc.IsMasterClientOrSingleplayer();
			for (int i = 1; i < 5; i++)
			{
				Limb limb = BodyParts.ToLimb(i);
				bool flag2 = (before & limb) != 0;
				bool flag3 = (after & limb) != 0;
				LimbPart limbPart = Find(avatar, i);
				if ((Object)(object)limbPart == (Object)null || flag2 == flag3)
				{
					continue;
				}
				if (flag3)
				{
					if (flag && !limbPart.Active && !avatar.deadSet)
					{
						PlaceFromBody(avatar, limbPart);
					}
					continue;
				}
				limbPart.ReleaseLocalGrab();
				if (flag)
				{
					limbPart.Hide();
				}
			}
		}

		internal static bool OnDeath(PlayerAvatar avatar)
		{
			if (!HasParts(avatar))
			{
				return false;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				Limb limb = LimbState.Get(avatar);
				PlaceFromBody(avatar, Find(avatar, 0));
				for (int i = 1; i < 5; i++)
				{
					LimbPart limbPart = Find(avatar, i);
					if ((limb & BodyParts.ToLimb(i)) == 0 && (Object)(object)limbPart != (Object)null && !limbPart.Active)
					{
						PlaceFromBody(avatar, limbPart);
					}
				}
			}
			return true;
		}

		internal static void OnRevive(PlayerAvatar avatar)
		{
			if (HasParts(avatar))
			{
				LimbPart limbPart = Find(avatar, 0);
				limbPart.ReleaseLocalGrab();
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					limbPart.Hide();
				}
				if (!SemiFunc.IsMultiplayer() || avatar.photonView.IsMine)
				{
					Limb limb = ((Random.value < 0.5f) ? Limb.LeftArm : Limb.RightArm);
					Limb limb2 = ((Random.value < 0.5f) ? Limb.LeftLeg : Limb.RightLeg);
					LimbState.SetLocal(Limb.All & ~(limb | limb2));
					Plugin.Log.LogInfo((object)$"Revive: fick tillbaka {limb} och {limb2}.");
				}
			}
		}

		private static void PlaceFromBody(PlayerAvatar avatar, LimbPart part)
		{
			//IL_003d: 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)
			BodyParts bodyParts = ((Component)avatar).GetComponent<LimbVisuals>()?.Parts;
			if (!((Object)(object)part == (Object)null) && bodyParts != null && !((Object)(object)bodyParts.Roots[part.Index] == (Object)null))
			{
				part.Place(bodyParts.Center(part.Index), bodyParts.Roots[part.Index].rotation);
			}
		}
	}
	internal static class LimbPartTemplate
	{
		internal const string PrefabId = "RepoLimbMod LimbPart";

		private static readonly HashSet<string> Keep = new HashSet<string> { "Transform", "Rigidbody", "PhotonView", "PhotonTransformView", "PhysGrabObject", "PhysGrabObjectImpactDetector", "RoomVolumeCheck", "NotValuableObject" };

		internal static GameObject Template { get; private set; }

		internal static void Register(LevelGenerator generator)
		{
			if ((Object)(object)Template == (Object)null)
			{
				if ((Object)(object)generator.PlayerDeathHeadPrefab == (Object)null)
				{
					Plugin.Log.LogError((object)"PlayerDeathHeadPrefab saknas, kroppsdelar kan inte skapas.");
					return;
				}
				Template = Build(generator.PlayerDeathHeadPrefab);
			}
			RunManager.instance.multiplayerPool.ResourceCache["RepoLimbMod LimbPart"] = Template;
		}

		private static GameObject Build(GameObject head)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0136: 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_014d: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("RepoLimbMod Templates");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			GameObject val2 = Object.Instantiate<GameObject>(head, val.transform);
			((Object)val2).name = "RepoLimbMod LimbPart";
			for (int num = val2.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num)).gameObject);
			}
			List<string> list = new List<string>();
			Component[] components;
			for (int i = 0; i < 4; i++)
			{
				components = val2.GetComponents<Component>();
				foreach (Component val3 in components)
				{
					if (!((Object)(object)val3 == (Object)null) && !Keep.Contains(((object)val3).GetType().Name))
					{
						string name = ((object)val3).GetType().Name;
						Object.DestroyImmediate((Object)(object)val3);
						if ((Object)(object)val3 == (Object)null && !list.Contains(name))
						{
							list.Add(name);
						}
					}
				}
			}
			PhotonView component = val2.GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null && component.ObservedComponents != null)
			{
				component.ObservedComponents.RemoveAll((Component c) => (Object)(object)c == (Object)null);
			}
			GameObject val4 = new GameObject("Collider");
			val4.transform.SetParent(val2.transform, false);
			val4.tag = "Phys Grab Object";
			val4.layer = LayerMask.NameToLayer("PhysGrabObject");
			val4.AddComponent<BoxCollider>().size = Vector3.one * 0.3f;
			val4.AddComponent<PhysGrabObjectCollider>();
			val2.AddComponent<LimbPart>();
			StringBuilder stringBuilder = new StringBuilder("Kroppsdelsmall skapad. Borttaget: ");
			stringBuilder.Append(string.Join(", ", list)).Append(". Kvar: ");
			List<string> list2 = new List<string>();
			components = val2.GetComponents<Component>();
			foreach (Component val5 in components)
			{
				list2.Add(((object)val5).GetType().Name);
			}
			stringBuilder.Append(string.Join(", ", list2));
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
			return val2;
		}

		internal static LimbPart Spawn(PlayerAvatar owner, int index)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			Vector3 physDisabledPosition = AssetManager.instance.physDisabledPosition;
			if (SemiFunc.IsMultiplayer())
			{
				GameObject val = PhotonNetwork.Instantiate("RepoLimbMod LimbPart", physDisabledPosition, Quaternion.identity, (byte)0, new object[2]
				{
					owner.photonView.ViewID,
					index
				});
				if (!((Object)(object)val != (Object)null))
				{
					return null;
				}
				return val.GetComponent<LimbPart>();
			}
			LimbPart component = Object.Instantiate<GameObject>(Template, physDisabledPosition, Quaternion.identity).GetComponent<LimbPart>();
			component.Init(owner.photonView.ViewID, index);
			component.Owner = owner;
			return component;
		}
	}
	[Flags]
	internal enum Limb
	{
		None = 0,
		LeftArm = 1,
		RightArm = 2,
		LeftLeg = 4,
		RightLeg = 8,
		Arms = 3,
		Legs = 0xC,
		All = 0xF
	}
	internal static class LimbState
	{
		internal static Limb Local;

		private static readonly Dictionary<int, Limb> remote = new Dictionary<int, Limb>();

		internal static Vector3? PendingHitPoint;

		internal static int LegsLost => Count(Local & Limb.Legs);

		internal static int ArmsLost => Count(Local & Limb.Arms);

		internal static Limb Get(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null)
			{
				return Limb.None;
			}
			if (!SemiFunc.IsMultiplayer() || avatar.photonView.IsMine)
			{
				return Local;
			}
			Player owner = avatar.photonView.Owner;
			if (owner == null || !remote.TryGetValue(owner.ActorNumber, out var value))
			{
				return Limb.None;
			}
			return value;
		}

		internal static void SetRemote(int actorNumber, Limb lost)
		{
			remote.TryGetValue(actorNumber, out var value);
			remote[actorNumber] = lost;
			if (value != lost)
			{
				LimbParts.OnStateChanged(FindByActor(actorNumber), value, lost);
			}
		}

		internal static void SetLocal(Limb lost)
		{
			Limb local = Local;
			Local = lost;
			if (local != lost)
			{
				LimbParts.OnStateChanged(PlayerAvatar.instance, local, lost);
			}
			LimbNetwork.Broadcast();
		}

		private static PlayerAvatar FindByActor(int actorNumber)
		{
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				Player val = (((Object)(object)player != (Object)null) ? player.photonView.Owner : null);
				if (val != null && val.ActorNumber == actorNumber)
				{
					return player;
				}
			}
			return null;
		}

		internal static int Count(Limb limbs)
		{
			int num = 0;
			for (int num2 = (int)limbs; num2 != 0; num2 &= num2 - 1)
			{
				num++;
			}
			return num;
		}

		internal static void ResetAll()
		{
			bool num = Local != Limb.None;
			remote.Clear();
			if (num)
			{
				Plugin.Log.LogInfo((object)"Lemmar återställda.");
				SetLocal(Limb.None);
			}
		}

		internal static void OnDamaged(int damage, int maxHealth, Vector3? hitPoint)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008c: Unknown result type (might be due to invalid IL or missing references)
			if (!hitPoint.HasValue)
			{
				return;
			}
			Vector3 valueOrDefault = hitPoint.GetValueOrDefault();
			if ((float)damage < (float)maxHealth * Plugin.Cfg.MinDamagePercent.Value)
			{
				return;
			}
			PlayerAvatar instance = PlayerAvatar.instance;
			if (!((Object)(object)instance == (Object)null) && TryGetBodyBounds(instance, out var bounds))
			{
				Limb limb = LimbAt(valueOrDefault, bounds, ((Component)instance.playerAvatarVisuals).transform);
				if ((Local & limb) == 0)
				{
					Plugin.Log.LogInfo((object)$"Förlorade {limb} (skada {damage}/{maxHealth}, träffpunkt {valueOrDefault}). Status: {Local | limb}");
					SetLocal(Local | limb);
				}
			}
		}

		internal static bool TryGetBodyBounds(PlayerAvatar avatar, out Bounds bounds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e7: 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_00f3: 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)
			bounds = default(Bounds);
			BodyParts bodyParts = ((!((Object)(object)avatar != (Object)null)) ? null : ((Component)avatar).GetComponent<LimbVisuals>()?.Parts);
			if (bodyParts == null)
			{
				return false;
			}
			bool flag = false;
			for (int i = 0; i < 5; i++)
			{
				foreach (Renderer item in bodyParts.Renderers[i])
				{
					object obj;
					if (!((Object)(object)item != (Object)null))
					{
						obj = null;
					}
					else
					{
						MeshFilter component = ((Component)item).GetComponent<MeshFilter>();
						obj = ((component != null) ? component.sharedMesh : null);
					}
					Mesh val = (Mesh)obj;
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Bounds bounds2 = val.bounds;
					for (int j = 0; j < 8; j++)
					{
						Vector3 val2 = ((Component)item).transform.TransformPoint(((Bounds)(ref bounds2)).center + Vector3.Scale(((Bounds)(ref bounds2)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))));
						if (flag)
						{
							((Bounds)(ref bounds)).Encapsulate(val2);
							continue;
						}
						bounds = new Bounds(val2, Vector3.zero);
						flag = true;
					}
				}
			}
			return flag;
		}

		private static Limb LimbAt(Vector3 hit, Bounds bounds, Transform body)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			bool num = Mathf.InverseLerp(((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y, hit.y) >= Plugin.Cfg.ArmZoneHeight.Value;
			float x = body.InverseTransformPoint(hit).x;
			bool flag = ((Mathf.Abs(x) < 0.05f) ? (Random.value < 0.5f) : (x < 0f));
			if (num)
			{
				if (!flag)
				{
					return Limb.RightArm;
				}
				return Limb.LeftArm;
			}
			if (!flag)
			{
				return Limb.RightLeg;
			}
			return Limb.LeftLeg;
		}
	}
	internal sealed class LimbVisuals : MonoBehaviour
	{
		private PlayerAvatar avatar;

		private Limb shown;

		internal BodyParts Parts { get; private set; }

		internal void Init(PlayerAvatar playerAvatar)
		{
			avatar = playerAvatar;
			if ((Object)(object)avatar.playerAvatarVisuals == (Object)null)
			{
				Plugin.Log.LogWarning((object)"PlayerAvatarVisuals saknas, lemmar kan inte döljas.");
			}
			else
			{
				Parts = BodyParts.Collect(avatar.playerAvatarVisuals);
			}
		}

		private void LateUpdate()
		{
			if ((Object)(object)avatar == (Object)null || Parts == null)
			{
				return;
			}
			Limb limb = LimbState.Get(avatar);
			for (int i = 1; i < 5; i++)
			{
				Limb limb2 = BodyParts.ToLimb(i);
				if ((limb & limb2) != Limb.None)
				{
					foreach (Renderer item in Parts.Renderers[i])
					{
						if ((Object)(object)item != (Object)null && item.enabled)
						{
							item.enabled = false;
						}
					}
				}
				else
				{
					if ((shown & limb2) == 0)
					{
						continue;
					}
					foreach (Renderer item2 in Parts.Renderers[i])
					{
						if ((Object)(object)item2 != (Object)null)
						{
							item2.enabled = true;
						}
					}
				}
			}
			shown = limb;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Start")]
	internal static class LevelGeneratorStartPatch
	{
		private static void Postfix(LevelGenerator __instance)
		{
			LimbPartTemplate.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "PlayerSpawn")]
	internal static class PlayerSpawnPatch
	{
		private static void Postfix()
		{
			LimbParts.SpawnAll();
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")]
	internal static class DeathDonePatch
	{
		private static void Prefix(PlayerAvatar __instance)
		{
			if (!__instance.isDisabled)
			{
				LimbParts.OnDeath(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerDeathEffects), "Trigger")]
	internal static class DeathEffectsPatch
	{
		private static bool Prefix(PlayerDeathEffects __instance)
		{
			PlayerAvatar val = (((Object)(object)__instance.playerAvatarVisuals != (Object)null) ? __instance.playerAvatarVisuals.playerAvatar : null);
			if (!((Object)(object)val == (Object)null))
			{
				return !LimbParts.HasParts(val);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")]
	internal static class RevivePatch
	{
		private static void Postfix(PlayerAvatar __instance)
		{
			if (!__instance.deadSet)
			{
				LimbParts.OnRevive(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerController), "Update")]
	internal static class ReattachPatch
	{
		private const float LookRange = 4.5f;

		private static void Postfix()
		{
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || instance.deadSet || (Object)(object)ItemInfoUI.instance == (Object)null)
			{
				return;
			}
			LimbPart limbPart = HeldPart() ?? LookedAtOwnPart(instance);
			if ((Object)(object)limbPart == (Object)null || (Object)(object)limbPart.Owner == (Object)null)
			{
				return;
			}
			string text = DisplayName(limbPart.Index);
			if (!((Object)(object)limbPart.Owner == (Object)(object)instance))
			{
				ItemInfoUI.instance.ItemInfoText((ItemAttributes)null, limbPart.Owner.playerName + "'s " + text, false);
			}
			else if (limbPart.Index != 0 && (LimbState.Local & limbPart.Limb) != Limb.None)
			{
				string text2 = SemiFunc.InputDisplayReplaceTags("[interact]", "<u><b>", "</b></u>");
				ItemInfoUI.instance.ItemInfoText((ItemAttributes)null, "Re-Attach " + text + " <color=#FFFFFF>[" + text2 + "]</color>", false);
				if (PlayerController.instance.InputDisableTimer <= 0f && SemiFunc.InputDown((InputKey)2))
				{
					Plugin.Log.LogInfo((object)$"Monterade tillbaka {limbPart.Limb}.");
					LimbState.SetLocal(LimbState.Local & ~limbPart.Limb);
				}
			}
		}

		private static LimbPart HeldPart()
		{
			foreach (LimbPart item in LimbPart.All)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item.Grab != (Object)null && item.Grab.grabbedLocal)
				{
					return item;
				}
			}
			return null;
		}

		private static LimbPart LookedAtOwnPart(PlayerAvatar avatar)
		{
			//IL_0020: 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_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 (LimbState.Local == Limb.None)
			{
				return null;
			}
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return null;
			}
			RaycastHit[] array = Physics.RaycastAll(((Component)main).transform.position, ((Component)main).transform.forward, 4.5f, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val = array[i];
				LimbPart componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<LimbPart>();
				if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.Owner == (Object)(object)avatar)
				{
					return componentInParent;
				}
			}
			return null;
		}

		private static string DisplayName(int index)
		{
			return index switch
			{
				1 => "Left Arm", 
				2 => "Right Arm", 
				3 => "Left Leg", 
				4 => "Right Leg", 
				_ => "Torso", 
			};
		}
	}
	[HarmonyPatch(typeof(PlayerHealth), "Hurt")]
	internal static class HurtPatch
	{
		private static void Prefix(PlayerHealth __instance, int enemyIndex, out int __state)
		{
			//IL_0049: 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)
			__state = __instance.health;
			if (!LimbState.PendingHitPoint.HasValue && enemyIndex >= 0)
			{
				Enemy val = SemiFunc.EnemyGetFromIndex(enemyIndex);
				if ((Object)(object)val != (Object)null)
				{
					LimbState.PendingHitPoint = (((Object)(object)val.CenterTransform != (Object)null) ? val.CenterTransform.position : ((Component)val).transform.position);
				}
			}
		}

		private static void Postfix(PlayerHealth __instance, int enemyIndex, int __state)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			int num = __state - __instance.health;
			Vector3? pendingHitPoint = LimbState.PendingHitPoint;
			LimbState.PendingHitPoint = null;
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)string.Format("Träff: {0}/{1} HP, fiende {2}, träffpunkt {3}, hälsa kvar {4}.", num, __instance.maxHealth, enemyIndex, (pendingHitPoint.HasValue ? ((object)pendingHitPoint.GetValueOrDefault()/*cast due to .constrained prefix*/).ToString() : null) ?? "saknas", __instance.health));
				if (__instance.health > 0 && !__instance.playerAvatar.deadSet && SemiFunc.RunIsLevel())
				{
					LimbState.OnDamaged(num, __instance.maxHealth, pendingHitPoint);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerHealth), "HurtOtherRPC")]
	internal static class HurtOtherPatch
	{
		private static void Prefix(PlayerHealth __instance, Vector3 hurtPosition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0019: 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)
			if (!(hurtPosition == Vector3.zero) && !(Vector3.Distance(hurtPosition, ((Component)__instance.playerAvatar).transform.position) < 0.1f))
			{
				LimbState.PendingHitPoint = hurtPosition;
			}
		}

		private static void Postfix()
		{
			LimbState.PendingHitPoint = null;
		}
	}
	[HarmonyPatch(typeof(HurtCollider), "PlayerHurt")]
	internal static class HurtColliderPatch
	{
		private static void Prefix(HurtCollider __instance, PlayerAvatar _player)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0044: 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_005d: 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)
			if (!((Object)(object)__instance.Collider == (Object)null) && (!SemiFunc.IsMultiplayer() || _player.photonView.IsMine) && LimbState.TryGetBodyBounds(_player, out var bounds))
			{
				Vector3 center = ((Bounds)(ref bounds)).center;
				Vector3 val = __instance.Collider.ClosestPoint(center);
				Vector3 value;
				if (!(val == center))
				{
					value = val;
				}
				else
				{
					Bounds bounds2 = __instance.Collider.bounds;
					value = ((Bounds)(ref bounds2)).center;
				}
				LimbState.PendingHitPoint = value;
			}
		}

		private static void Postfix()
		{
			LimbState.PendingHitPoint = null;
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "Start")]
	internal static class AvatarStartPatch
	{
		private static bool dumped;

		private static void Postfix(PlayerAvatar __instance)
		{
			LimbNetwork.EnsureRegistered();
			if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<LimbVisuals>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<LimbVisuals>().Init(__instance);
			}
			if (!SemiFunc.IsMultiplayer() || __instance.photonView.IsMine)
			{
				if (SemiFunc.RunIsShop() || SemiFunc.MenuLevel() || SemiFunc.RunIsArena())
				{
					LimbState.ResetAll();
				}
				else
				{
					LimbNetwork.Broadcast();
				}
				if (!dumped && Plugin.Cfg.DumpHierarchy.Value && (Object)(object)__instance.playerAvatarVisuals != (Object)null)
				{
					dumped = true;
					StringBuilder stringBuilder = new StringBuilder("Spelarmodellens hierarki:\n");
					Dump(((Component)__instance.playerAvatarVisuals).transform, 0, stringBuilder);
					Plugin.Log.LogInfo((object)stringBuilder.ToString());
				}
			}
		}

		private static void Dump(Transform t, int depth, StringBuilder sb)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			sb.Append(' ', depth * 2).Append(((Object)t).name);
			if ((Object)(object)((Component)t).GetComponent<Renderer>() != (Object)null)
			{
				sb.Append(" [Renderer]");
			}
			sb.Append('\n');
			foreach (Transform item in t)
			{
				Dump(item, depth + 1, sb);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
	internal static class ControllerFixedUpdatePatch
	{
		private static void Prefix(PlayerController __instance, out float __state)
		{
			__state = __instance.JumpForce;
			int legsLost = LimbState.LegsLost;
			if (legsLost != 0)
			{
				__instance.toggleSprint = false;
				if (legsLost >= 2)
				{
					__instance.CrouchOverride(0.2f);
				}
				else
				{
					__instance.JumpForce *= Plugin.Cfg.OneLegJump.Value;
				}
			}
		}

		private static void Postfix(PlayerController __instance, float __state)
		{
			__instance.JumpForce = __state;
		}
	}
	[HarmonyPatch(typeof(PlayerController), "OverrideSpeedLogic")]
	internal static class SpeedPatch
	{
		private static bool applied;

		private static void Postfix(PlayerController __instance)
		{
			if (!(__instance.overrideTimeScaleTimer > 0f))
			{
				float num = SpeedMultiplier();
				if (!(num >= 1f) || applied)
				{
					float num2 = ((__instance.overrideSpeedTimer > 0f) ? __instance.overrideSpeedMultiplier : 1f);
					__instance.MoveSpeed = __instance.playerOriginalMoveSpeed * num2 * num;
					__instance.SprintSpeed = __instance.playerOriginalSprintSpeed * num2 * num;
					__instance.CrouchSpeed = __instance.playerOriginalCrouchSpeed * num2 * num;
					applied = num < 1f;
				}
			}
		}

		private static float SpeedMultiplier()
		{
			return LimbState.LegsLost switch
			{
				0 => 1f, 
				1 => Plugin.Cfg.OneLegSpeed.Value, 
				_ => Plugin.Cfg.NoLegsSpeed.Value, 
			};
		}
	}
	[HarmonyPatch(typeof(PhysGrabber), "Update")]
	internal static class GrabberUpdatePatch
	{
		private static void Prefix(PhysGrabber __instance)
		{
			int num = LimbState.Count(LimbState.Get(__instance.playerAvatar) & Limb.Arms);
			if (num == 1)
			{
				__instance.OverrideGrabStrength(__instance.grabStrength * Plugin.Cfg.OneArmGrabStrength.Value, 0.2f);
			}
			else if (num >= 2 && __instance.isLocal)
			{
				__instance.toggleGrab = false;
			}
		}
	}
	[HarmonyPatch]
	internal static class InputPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(InputManager), "KeyHold", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(InputManager), "KeyDown", (Type[])null, (Type[])null);
		}

		private static bool Prefix(InputKey key, ref bool __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!Blocks(key))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool Blocks(InputKey key)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			if (LimbState.Local == Limb.None)
			{
				return false;
			}
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || instance.deadSet)
			{
				return false;
			}
			if ((int)key <= 10)
			{
				if ((int)key == 1)
				{
					return LimbState.LegsLost >= 2;
				}
				if ((int)key == 10)
				{
					return LimbState.ArmsLost >= 2;
				}
			}
			else
			{
				if ((int)key == 11)
				{
					if (LimbState.ArmsLost == 1)
					{
						return Plugin.Cfg.OneArmBlocksRotate.Value;
					}
					return false;
				}
				if ((int)key == 15)
				{
					return LimbState.LegsLost >= 1;
				}
			}
			return false;
		}
	}
	[BepInPlugin("kinglir.repolimbmod", "RepoLimbMod", "0.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "kinglir.repolimbmod";

		public const string Name = "RepoLimbMod";

		public const string Version = "0.2.1";

		internal static ManualLogSource Log;

		internal static LimbConfig Cfg;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg = new LimbConfig(((BaseUnityPlugin)this).Config);
			new Harmony("kinglir.repolimbmod").PatchAll();
			Log.LogInfo((object)"RepoLimbMod 0.2.1 laddad.");
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}