Decompiled source of PreciseRotation v26.2.0

plugins\PreciseRotation\PreciseRotation.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PreciseRotation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PreciseRotation")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("26.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("26.2.0.0")]
namespace PreciseRotation;

[BepInPlugin("com.github.johndowson.PreciseRotation", "PreciseRotation", "26.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
internal class PreciseRotation : BaseUnityPlugin
{
	private struct Rotator
	{
		public enum Axis
		{
			X,
			Y,
			Z
		}

		public Axis CurrentAxis;

		public float DegreesPerStep;

		public int fineMult;

		public float x;

		public float y;

		public float z;

		public bool Precision;

		public Rotator(int stepsCoarse, int fineMult)
		{
			CurrentAxis = Axis.Y;
			x = (y = (z = 0f));
			Precision = false;
			DegreesPerStep = 180f / (float)(stepsCoarse * fineMult);
			this.fineMult = fineMult;
		}

		public void Rotate(int steps)
		{
			steps = (Precision ? steps : (steps * fineMult));
			float num = DegreesPerStep * (float)steps;
			switch (CurrentAxis)
			{
			case Axis.X:
				x += num;
				break;
			case Axis.Y:
				y += num;
				break;
			case Axis.Z:
				z += num;
				break;
			}
		}

		public readonly Quaternion GetRotatation()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(x, y, z);
		}

		public void NextAxis()
		{
			CurrentAxis = CurrentAxis switch
			{
				Axis.X => Axis.Y, 
				Axis.Y => Axis.Z, 
				Axis.Z => Axis.X, 
				_ => throw new ArgumentOutOfRangeException(), 
			};
		}
	}

	[HarmonyPatch(typeof(Player))]
	public static class PieceRotation_Patch
	{
		[HarmonyPatch("UpdatePlacementGhost")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> UpdatePlacementGhostPatch(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && list[i + 1].opcode == OpCodes.Ldarg_0 && list[i + 2].opcode == OpCodes.Ldfld && list[i + 3].opcode == OpCodes.Ldarg_0 && list[i + 4].opcode == OpCodes.Ldfld && list[i + 5].opcode == OpCodes.Conv_R4 && list[i + 6].opcode == OpCodes.Mul && list[i + 7].opcode == OpCodes.Ldc_R4 && list[i + 8].opcode == OpCodes.Call)
				{
					list[i].opcode = OpCodes.Ldarg_0;
					list[i + 1] = new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo<Player, Quaternion>((Expression<Func<Player, Quaternion>>)((Player player) => GetRotatation(player))));
					for (int j = 2; j <= 8; j++)
					{
						list[i + j].opcode = OpCodes.Nop;
					}
				}
			}
			return list.AsEnumerable();
		}

		[HarmonyPatch("UpdatePlacement")]
		[HarmonyPrefix]
		private static void RememberOldRotation(Player __instance, bool takeInput, float dt, ref int __state)
		{
			__state = __instance.m_placeRotation;
		}

		[HarmonyPatch("UpdatePlacement")]
		[HarmonyPostfix]
		private static void StoreRotationDifference(Player __instance, bool takeInput, float dt, ref int __state)
		{
			if (!((Object)(object)Player.m_localPlayer != (Object)(object)__instance))
			{
				int steps = __instance.m_placeRotation - __state;
				rotator.Rotate(steps);
			}
		}
	}

	public const string PluginGUID = "com.github.johndowson.PreciseRotation";

	public const string PluginName = "PreciseRotation";

	public const string PluginVersion = "26.2.0";

	private static readonly Harmony harmony = new Harmony("com.github.johndowson.PreciseRotation");

	private ConfigEntry<int> RotationStepsCoarse;

	private ConfigEntry<int> RotationStepsFineMultiplier;

	private ConfigEntry<bool> ToggleRotation;

	private ConfigEntry<KeyCode> RotationModifierKeyboard;

	private ConfigEntry<GamepadButton> RotationModifierGamepad;

	private ButtonConfig RotationModifier;

	private ConfigEntry<KeyCode> NextAxisKeyboard;

	private ConfigEntry<GamepadButton> NextAxisGamepad;

	private ButtonConfig NextAxis;

	public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

	private static Rotator rotator;

	private static Sprite X;

	private static Sprite Y;

	private static Sprite Z;

	private void Awake()
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Expected O, but got Unknown
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Expected O, but got Unknown
		X = AssetUtils.LoadSpriteFromFile("PreciseRotation/Assets/axis_x.png");
		Y = AssetUtils.LoadSpriteFromFile("PreciseRotation/Assets/axis_y.png");
		Z = AssetUtils.LoadSpriteFromFile("PreciseRotation/Assets/axis_z.png");
		ToggleRotation = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "ToggleRotation", false, "Key to toggle precise rotation");
		RotationModifierKeyboard = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "RotationModifierKeyboard", (KeyCode)308, "Key to toggle precise rotation");
		RotationModifierGamepad = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Controls", "RotationModifierGamepad", (GamepadButton)0, "Key to toggle precise rotation");
		RotationModifier = new ButtonConfig
		{
			Name = "RotationModifier",
			Config = RotationModifierKeyboard,
			GamepadConfig = RotationModifierGamepad,
			HintToken = "$RotationModifierHint",
			BlockOtherInputs = false
		};
		InputManager.Instance.AddButton("com.github.johndowson.PreciseRotation", RotationModifier);
		NextAxisKeyboard = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "NextAxisKeyboard", (KeyCode)46, "Key to toggle rotation axis");
		NextAxisGamepad = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Controls", "NextAxisGamepad", (GamepadButton)0, "Key to toggle rotation axis");
		NextAxis = new ButtonConfig
		{
			Name = "NextAxis",
			Config = NextAxisKeyboard,
			GamepadConfig = NextAxisGamepad,
			HintToken = "$NextAxisHint",
			BlockOtherInputs = true
		};
		InputManager.Instance.AddButton("com.github.johndowson.PreciseRotation", NextAxis);
		RotationStepsCoarse = ((BaseUnityPlugin)this).Config.Bind<int>("Rotation", "StepsCoarse", 16, "Base number of rotation steps per 180 degrees, Valheim's default is 16");
		RotationStepsFineMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Rotation", "FineMultiplier", 2, "Multiply StepsCoarse by this number to get precise mode steps per 180");
		rotator = new Rotator(RotationStepsCoarse.Value, RotationStepsFineMultiplier.Value);
		harmony.PatchAll();
		Logger.LogInfo((object)"PreciseRotation has landed");
	}

	private void Update()
	{
		if (ZInput.instance != null && (Object)(object)Player.m_localPlayer != (Object)null)
		{
			if (ToggleRotation.Value && ZInput.GetButtonDown(RotationModifier.Name))
			{
				rotator.Precision = !rotator.Precision;
				((Character)Player.m_localPlayer).Message((MessageType)1, "Precise Rotation " + (rotator.Precision ? "On" : "Off"), 0, (Sprite)null);
			}
			else
			{
				rotator.Precision = ZInput.GetButton(RotationModifier.Name);
			}
			Logger.LogFatal((object)$"Prec: {rotator.Precision};");
			if (ZInput.GetButtonDown(NextAxis.Name))
			{
				rotator.NextAxis();
				Sprite val = (Sprite)(rotator.CurrentAxis switch
				{
					Rotator.Axis.X => X, 
					Rotator.Axis.Y => Y, 
					Rotator.Axis.Z => Z, 
					_ => throw new ArgumentOutOfRangeException(), 
				});
				((Character)Player.m_localPlayer).Message((MessageType)1, "Rotation Axis", 0, val);
			}
		}
	}

	public static Quaternion GetRotatation(Player player)
	{
		//IL_0030: 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)
		if ((Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			return Quaternion.Euler(0f, player.m_placeRotationDegrees * (float)player.m_placeRotation, 0f);
		}
		return rotator.GetRotatation();
	}
}