Decompiled source of TwoPinPull v0.1.0

BepInEx/plugins/TwoPinPull/TwoPinPull.dll

Decompiled a day ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("TwoPinPull")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+64c7a9b39f510fb8ba21ab3b80c61d1e1a46ae57")]
[assembly: AssemblyProduct("TwoPinPull")]
[assembly: AssemblyTitle("TwoPinPull")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TwoPinPull;

[BepInPlugin("invent60.h3vr.twopinpull", "Two Pin Pull", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<bool> NeedGrip;

	internal static ConfigEntry<bool> DebugLog;

	private void Awake()
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Holding a grenade's pin ring and pulling the trigger too pulls all of its pins at once. false = one pin at a time, as in the game.\nExample: Enabled = false");
		NeedGrip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Grip and trigger", true, "true = both pins come out only while the grip AND the trigger are held (grip alone = one pin). false = the trigger alone is enough\n(for players who grab with the trigger: then every pull takes all pins).\nExample: Grip and trigger = false");
		DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log", false, "Writes a line each time pins are pulled together (which grenade, how many pins).\nExample: Log = true");
		if (!Rings.Ready())
		{
			Log.LogWarning((object)"Two Pin Pull: the game's grenade ring fields were not found (game update?); the mod does nothing.");
			return;
		}
		new Harmony("invent60.h3vr.twopinpull").PatchAll(typeof(RingPatch));
		if (DebugLog.Value)
		{
			Log.LogInfo((object)"Two Pin Pull ready.");
		}
	}
}
internal static class Rings
{
	private const BindingFlags Inst = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static readonly FieldInfo s_rings = typeof(PinnedGrenade).GetField("m_rings", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo s_posMin = typeof(PinnedGrenadeRing).GetField("m_posMin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo s_posMax = typeof(PinnedGrenadeRing).GetField("m_posMax", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo s_posCurrent = typeof(PinnedGrenadeRing).GetField("m_posCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo s_detached = typeof(PinnedGrenadeRing).GetField("m_hasPinDetached", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo s_swapped = typeof(PinnedGrenadeRing).GetField("m_hasSwapped", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	public static bool Ready()
	{
		if ((object)s_rings != null && (object)s_posMin != null && (object)s_posMax != null && (object)s_posCurrent != null && (object)s_detached != null)
		{
			return (object)s_swapped != null;
		}
		return false;
	}

	public static List<PinnedGrenadeRing> Of(PinnedGrenade g)
	{
		if (!((Object)(object)g != (Object)null))
		{
			return null;
		}
		return s_rings.GetValue(g) as List<PinnedGrenadeRing>;
	}

	public static float Out(PinnedGrenadeRing r)
	{
		return Mathf.InverseLerp((float)s_posMin.GetValue(r), (float)s_posMax.GetValue(r), (float)s_posCurrent.GetValue(r));
	}

	public static void SetOut(PinnedGrenadeRing r, float f)
	{
		//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_005f: 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_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		if (f <= Out(r))
		{
			return;
		}
		float num = Mathf.Lerp((float)s_posMin.GetValue(r), (float)s_posMax.GetValue(r), Mathf.Clamp01(f) * 0.999f);
		s_posCurrent.SetValue(r, num);
		Vector3 localPosition = ((Component)r).transform.localPosition;
		((Component)r).transform.localPosition = new Vector3(localPosition.x, localPosition.y, num);
		if ((Object)(object)r.Pin != (Object)null)
		{
			Vector3 localPosition2 = ((Component)r.Pin).transform.localPosition;
			((Component)r.Pin).transform.localPosition = new Vector3(localPosition2.x, localPosition2.y, num);
		}
		if (r.UsesSwapPin && !(bool)s_swapped.GetValue(r) && (Object)(object)r.Pin != (Object)null)
		{
			s_swapped.SetValue(r, true);
			MeshFilter component = ((Component)r.Pin).GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null)
			{
				component.mesh = r.SwapPin;
			}
		}
	}

	public static void Free(PinnedGrenadeRing r, FVRViveHand hand)
	{
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		if (!r.HasPinDetached() && !((Object)(object)r.Pin == (Object)null))
		{
			s_detached.SetValue(r, true);
			if (((FVRInteractiveObject)r).IsHeld)
			{
				((FVRInteractiveObject)r).ForceBreakInteraction();
			}
			Rigidbody val = ((Component)r.Pin).gameObject.GetComponent<Rigidbody>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)r.Pin).gameObject.AddComponent<Rigidbody>();
			}
			val.mass = 0.02f;
			r.Pin.RootRigidbody = val;
			((Component)r).transform.SetParent(((Component)r.Pin).transform);
			((Behaviour)r.Pin).enabled = true;
			if ((Object)(object)hand != (Object)null)
			{
				val.velocity = hand.Input.VelLinearWorld;
			}
			Collider component = ((Component)r).GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				component.enabled = false;
			}
			((Behaviour)r).enabled = false;
		}
	}
}
[HarmonyPatch(typeof(PinnedGrenadeRing), "FVRUpdate")]
internal static class RingPatch
{
	private static bool Pulling(PinnedGrenadeRing r)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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 (!Plugin.Enabled.Value || !((FVRInteractiveObject)r).IsHeld || (Object)(object)((FVRInteractiveObject)r).m_hand == (Object)null || r.HasPinDetached())
		{
			return false;
		}
		HandInput input = ((FVRInteractiveObject)r).m_hand.Input;
		if (input.TriggerPressed)
		{
			if (Plugin.NeedGrip.Value)
			{
				return input.GripPressed;
			}
			return true;
		}
		return false;
	}

	private static void Prefix(PinnedGrenadeRing __instance, out FVRViveHand __state)
	{
		__state = (Pulling(__instance) ? ((FVRInteractiveObject)__instance).m_hand : null);
	}

	private static void Postfix(PinnedGrenadeRing __instance, FVRViveHand __state)
	{
		if ((Object)(object)__state == (Object)null)
		{
			return;
		}
		List<PinnedGrenadeRing> list = Rings.Of(__instance.G);
		if (list == null || list.Count < 2)
		{
			return;
		}
		bool flag = __instance.HasPinDetached();
		float f = (flag ? 1f : Rings.Out(__instance));
		int num = 0;
		foreach (PinnedGrenadeRing item in list)
		{
			if (!((Object)(object)item == (Object)null) && item != __instance && !item.HasPinDetached() && !((FVRInteractiveObject)item).IsHeld)
			{
				if (flag)
				{
					Rings.Free(item, __state);
				}
				else
				{
					Rings.SetOut(item, f);
				}
				num++;
			}
		}
		if (flag && num > 0 && Plugin.DebugLog.Value)
		{
			Plugin.Log.LogInfo((object)("Two Pin Pull: " + ((Object)__instance.G).name + ": " + (num + 1) + " pins pulled together"));
		}
	}
}