Decompiled source of Front Fanny Pack v1.0.0

FrontFannyPack.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("FrontFannyPack")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FrontFannyPack")]
[assembly: AssemblyTitle("FrontFannyPack")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FrontFannyPack
{
	internal static class FannyUtil
	{
		internal static bool IsFannypackWorn(Character character)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			if ((Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null)
			{
				return false;
			}
			BackpackSlot backpackSlot = character.player.backpackSlot;
			if (backpackSlot == null || (int)backpackSlot.backpackType != 2)
			{
				return false;
			}
			CharacterItems val = ((character.refs != null) ? character.refs.items : null);
			if ((Object)(object)val != (Object)null && val.currentSelectedSlot.IsSome && val.currentSelectedSlot.Value == 3)
			{
				return false;
			}
			return true;
		}

		internal static bool IsLookingFullyDown()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)MainCamera.instance == (Object)null)
			{
				return false;
			}
			return Vector3.Angle(Vector3.down, ((Component)MainCamera.instance).transform.forward) <= Plugin.ShowLookDownLimit;
		}

		internal static bool IsLocalPackVisible()
		{
			if (!Plugin.AlwaysShowLocalEnabled)
			{
				if (Plugin.ShowLocalEnabled)
				{
					return IsLookingFullyDown();
				}
				return false;
			}
			return true;
		}

		internal static bool CanSelfAccess(Character character)
		{
			if (!Plugin.AccessEnabled || !IsFannypackWorn(character))
			{
				return false;
			}
			if (!Plugin.ClimbingAllowed && (Object)(object)character.data != (Object)null && character.data.isClimbingAnything)
			{
				return false;
			}
			if (character.IsLocal && !MainCameraMovement.IsSpectating)
			{
				return IsLocalPackVisible();
			}
			return IsLookingFullyDown();
		}

		internal static BackpackOnBackVisuals GetFannypackVisuals(Character character)
		{
			if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.backpackHandler == (Object)null)
			{
				return null;
			}
			return character.refs.backpackHandler.fannypackVisuals;
		}

		internal static Bodypart GetHip(Character character)
		{
			if ((Object)(object)character == (Object)null || character.refs == null)
			{
				return null;
			}
			return character.refs.hip;
		}

		internal static Vector3 GetHipPosition(Character character)
		{
			//IL_0022: 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)
			Bodypart hip = GetHip(character);
			if ((Object)(object)hip == (Object)null)
			{
				return ((Component)character).transform.position;
			}
			return hip.transform.position;
		}
	}
	[HarmonyPatch(typeof(BackpackOnBackVisuals), "IsInteractible")]
	internal static class SelfInteractiblePatch
	{
		private static void Postfix(BackpackOnBackVisuals __instance, Character interactor, ref bool __result)
		{
			SelfPrompt.ApplySelfPrompt(__instance, interactor, ref __result);
		}
	}
	[HarmonyPatch(typeof(BackpackOnBackVisuals), "IsConstantlyInteractable")]
	internal static class SelfConstantPatch
	{
		private static void Postfix(BackpackOnBackVisuals __instance, Character interactor, ref bool __result)
		{
			SelfPrompt.ApplySelfPrompt(__instance, interactor, ref __result);
		}
	}
	internal static class SelfPrompt
	{
		internal static void ApplySelfPrompt(BackpackOnBackVisuals instance, Character interactor, ref bool result)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)interactor == (Object)null) && (int)instance.backpackType == 2 && !((Object)(object)interactor != (Object)(object)instance.character) && interactor.IsLocal && !MainCameraMovement.IsSpectating)
			{
				result = FannyUtil.CanSelfAccess(interactor);
			}
		}
	}
	[HarmonyPatch(typeof(Interaction), "DoInteractableRaycasts")]
	internal static class LookDownRaycastPatch
	{
		private static void Postfix(ref IInteractible interactableResult)
		{
			Character localCharacter = Character.localCharacter;
			BackpackOnBackVisuals fannypackVisuals = FannyUtil.GetFannypackVisuals(localCharacter);
			if (FannyUtil.CanSelfAccess(localCharacter))
			{
				if (interactableResult == null && (Object)(object)fannypackVisuals != (Object)null)
				{
					interactableResult = (IInteractible)(object)fannypackVisuals;
				}
			}
			else if ((Object)(object)fannypackVisuals != (Object)null && (object)interactableResult == fannypackVisuals)
			{
				interactableResult = null;
			}
		}
	}
	[BepInProcess("PEAK.exe")]
	[BepInPlugin("com.daedo.frontfannypack", "Front Fanny Pack", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.daedo.frontfannypack";

		public const string Name = "Front Fanny Pack";

		public const string Version = "1.0.0";

		internal static ConfigEntry<bool> MoveToFront;

		internal static ConfigEntry<bool> LookDownAccess;

		internal static ConfigEntry<bool> ShowLocalWhenLookingDown;

		internal static ConfigEntry<bool> AlwaysShowLocal;

		internal static ConfigEntry<bool> AllowWhileClimbing;

		internal static ConfigEntry<float> LookDownMaxAngleFromDown;

		internal static ConfigEntry<float> ShowLookDownMaxAngleFromDown;

		internal static ConfigEntry<float> ExtraFrontPush;

		internal static ConfigEntry<float> HeightAdjust;

		internal static ManualLogSource Log { get; private set; }

		internal static bool MoveEnabled
		{
			get
			{
				if (MoveToFront != null)
				{
					return MoveToFront.Value;
				}
				return true;
			}
		}

		internal static bool AccessEnabled
		{
			get
			{
				if (LookDownAccess != null)
				{
					return LookDownAccess.Value;
				}
				return true;
			}
		}

		internal static bool ShowLocalEnabled
		{
			get
			{
				if (ShowLocalWhenLookingDown != null)
				{
					return ShowLocalWhenLookingDown.Value;
				}
				return true;
			}
		}

		internal static bool AlwaysShowLocalEnabled
		{
			get
			{
				if (AlwaysShowLocal != null)
				{
					return AlwaysShowLocal.Value;
				}
				return false;
			}
		}

		internal static bool ClimbingAllowed
		{
			get
			{
				if (AllowWhileClimbing != null)
				{
					return AllowWhileClimbing.Value;
				}
				return true;
			}
		}

		internal static float LookDownLimit => LookDownMaxAngleFromDown?.Value ?? 55f;

		internal static float ShowLookDownLimit => ShowLookDownMaxAngleFromDown?.Value ?? 12f;

		internal static float ExtraFront => ExtraFrontPush?.Value ?? 0f;

		internal static float HeightOffset => HeightAdjust?.Value ?? 0f;

		private void Awake()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			MoveToFront = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "MoveToFront", true, "Wear the fanny pack on the front of your waist. Same model and size, just turned around.");
			ShowLocalWhenLookingDown = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowLocalWhenLookingDown", true, "Show the fanny pack in first person when you look all the way down.");
			ShowLookDownMaxAngleFromDown = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "ShowLookDownMaxAngleFromDown", 12f, new ConfigDescription("How far down you need to look to see the fanny pack in first person. 0 = straight at the ground, 12 = almost at your feet.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 45f), Array.Empty<object>()));
			AlwaysShowLocal = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "AlwaysShowLocal", false, "Always show the fanny pack in first person.");
			ExtraFrontPush = ((BaseUnityPlugin)this).Config.Bind<float>("Attach", "ExtraFrontPush", 0f, "Move it further forward (+) or closer to the body (-). 0 = default position.");
			HeightAdjust = ((BaseUnityPlugin)this).Config.Bind<float>("Attach", "HeightAdjust", 0f, "Move it up (+) or down (-) on the waist. 0 = vanilla height.");
			LookDownAccess = ((BaseUnityPlugin)this).Config.Bind<bool>("Access", "LookDownAccess", true, "Look down and press the interact key to open the fanny pack without taking it off. The prompt only shows while the fanny pack is visible.");
			LookDownMaxAngleFromDown = ((BaseUnityPlugin)this).Config.Bind<float>("Access", "LookDownMaxAngleFromDown", 55f, new ConfigDescription("Maximum angle between your view and straight down to open it. 0 = ground, 90 = horizon.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 80f), Array.Empty<object>()));
			AllowWhileClimbing = ((BaseUnityPlugin)this).Config.Bind<bool>("Access", "AllowWhileClimbing", true, "Allow opening the fanny pack while climbing.");
			try
			{
				new Harmony("com.daedo.frontfannypack").PatchAll();
				Log.LogInfo((object)"Front Fanny Pack v1.0.0 loaded.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to apply patches: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(CharacterBackpackHandler), "LateUpdate")]
	internal static class VisualPatch
	{
		private sealed class AttachState
		{
			public Transform OriginalParent;

			public Vector3 OriginalLocalPos;

			public Quaternion OriginalLocalRot;

			public Vector3 OriginalLocalScale;

			public Vector3 FrontLocalPos;

			public Quaternion FrontLocalRot;

			public float BakedExtraFront;

			public float BakedHeight;

			public bool FrontPoseReady;

			public bool Front;
		}

		private static readonly Dictionary<int, AttachState> States = new Dictionary<int, AttachState>();

		private static bool LoggedOnce;

		private static void Postfix(CharacterBackpackHandler __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			BackpackOnBackVisuals fannypackVisuals = __instance.fannypackVisuals;
			if (!((Object)(object)component == (Object)null) && !((Object)(object)fannypackVisuals == (Object)null))
			{
				bool flag = FannyUtil.IsFannypackWorn(component);
				if (Plugin.MoveEnabled && flag)
				{
					AttachFront(fannypackVisuals, component);
				}
				else
				{
					Restore(fannypackVisuals);
				}
				if (flag && component.IsLocal && !MainCameraMovement.IsSpectating && FannyUtil.IsLocalPackVisible())
				{
					fannypackVisuals.SetViewActive(true);
				}
			}
		}

		private static void AttachFront(BackpackOnBackVisuals visuals, Character character)
		{
			//IL_0069: 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_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)
			int instanceID = ((Object)visuals).GetInstanceID();
			if (!States.TryGetValue(instanceID, out var value))
			{
				value = Capture(visuals);
				States[instanceID] = value;
			}
			if ((Object)(object)value.OriginalParent == (Object)null)
			{
				return;
			}
			if ((Object)(object)((Component)visuals).transform.parent != (Object)(object)value.OriginalParent)
			{
				((Component)visuals).transform.SetParent(value.OriginalParent, false);
				((Component)visuals).transform.localScale = value.OriginalLocalScale;
			}
			if (!value.FrontPoseReady || value.BakedExtraFront != Plugin.ExtraFront || value.BakedHeight != Plugin.HeightOffset)
			{
				BakeFrontLocal(value, character);
			}
			if (!value.FrontPoseReady)
			{
				return;
			}
			if (!value.Front)
			{
				value.Front = true;
				if (!LoggedOnce)
				{
					LoggedOnce = true;
					Plugin.Log.LogInfo((object)"Fanny pack moved to the front of the waist.");
				}
			}
			((Component)visuals).transform.localPosition = value.FrontLocalPos;
			((Component)visuals).transform.localRotation = value.FrontLocalRot;
			((Component)visuals).transform.localScale = value.OriginalLocalScale;
		}

		private static void BakeFrontLocal(AttachState state, Character character)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			Transform originalParent = state.OriginalParent;
			if (!((Object)(object)originalParent == (Object)null))
			{
				Vector3 val = originalParent.TransformPoint(state.OriginalLocalPos);
				Quaternion val2 = originalParent.rotation * state.OriginalLocalRot;
				Vector3 val3 = FannyUtil.GetHipPosition(character) - val;
				val3.y = 0f;
				Vector3 val4 = val + 2f * val3;
				val4.y = val.y + Plugin.HeightOffset;
				Vector3 val5 = val4 - val;
				val5.y = 0f;
				if (Mathf.Abs(Plugin.ExtraFront) > 0.0001f && ((Vector3)(ref val5)).sqrMagnitude > 0.0001f)
				{
					val4 += ((Vector3)(ref val5)).normalized * Plugin.ExtraFront;
				}
				Quaternion val6 = Quaternion.AngleAxis(180f, Vector3.up) * val2;
				state.FrontLocalPos = originalParent.InverseTransformPoint(val4);
				state.FrontLocalRot = Quaternion.Inverse(originalParent.rotation) * val6;
				state.BakedExtraFront = Plugin.ExtraFront;
				state.BakedHeight = Plugin.HeightOffset;
				state.FrontPoseReady = true;
			}
		}

		private static AttachState Capture(BackpackOnBackVisuals visuals)
		{
			//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_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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			return new AttachState
			{
				OriginalParent = ((Component)visuals).transform.parent,
				OriginalLocalPos = ((Component)visuals).transform.localPosition,
				OriginalLocalRot = ((Component)visuals).transform.localRotation,
				OriginalLocalScale = ((Component)visuals).transform.localScale
			};
		}

		private static void Restore(BackpackOnBackVisuals visuals)
		{
			//IL_0038: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)visuals).GetInstanceID();
			if (States.TryGetValue(instanceID, out var value) && value.Front)
			{
				((Component)visuals).transform.SetParent(value.OriginalParent, false);
				((Component)visuals).transform.localPosition = value.OriginalLocalPos;
				((Component)visuals).transform.localRotation = value.OriginalLocalRot;
				((Component)visuals).transform.localScale = value.OriginalLocalScale;
				value.Front = false;
				value.FrontPoseReady = false;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}