Decompiled source of AdvancedHammerRotation v1.0.0

AdvancedHammerRotation.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AdvancedHammerRotation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AdvancedHammerRotation")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("12f8fdf0-eca8-4f90-9a1d-f2d81840d8a4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AdvancedHammerRotation;

[BepInPlugin("robit.valheim.advancedhammerrotation", "Axis Rotation", "1.0.0")]
public class AdvancedHammerRotationPlugin : BaseUnityPlugin
{
	private enum RotationAxis
	{
		Y,
		X,
		Z
	}

	[HarmonyPatch(typeof(Player), "UpdatePlacement", new Type[]
	{
		typeof(bool),
		typeof(float)
	})]
	private static class Player_UpdatePlacement_Patch
	{
		private static void Postfix(Player __instance, bool takeInput, float dt)
		{
			//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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !takeInput || !((Character)__instance).InPlaceMode() || !RotationEnabledForCurrentTool(__instance) || ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_buildHud != (Object)null && Hud.instance.m_buildHud.activeSelf && (Object)(object)Hud.instance.m_pieceSelectionWindow != (Object)null && Hud.instance.m_pieceSelectionWindow.activeSelf))
			{
				return;
			}
			KeyboardShortcut value = ResetRotationKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				ResetRotation();
				return;
			}
			value = CycleAxisKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				CycleAxis();
				return;
			}
			int num = Math.Sign(Input.GetAxis("Mouse ScrollWheel"));
			if (num != 0)
			{
				Rotate(num);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	private static class Player_UpdatePlacementGhost_Patch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Quaternion), "Euler", new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(float)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(AdvancedHammerRotationPlugin), "GetPlacementRotation", (Type[])null, (Type[])null);
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_placeRotation");
			bool flag = false;
			for (int i = 0; i < list.Count; i++)
			{
				if (!CodeInstructionExtensions.Calls(list[i], methodInfo))
				{
					continue;
				}
				bool flag2 = false;
				for (int j = Math.Max(0, i - 12); j < i; j++)
				{
					if (list[j].operand is FieldInfo fieldInfo2 && fieldInfo2 == fieldInfo)
					{
						flag2 = true;
						break;
					}
				}
				if (flag2)
				{
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
					flag = true;
					Log.LogInfo((object)"Patched Valheim placement rotation successfully.");
					break;
				}
			}
			if (!flag)
			{
				Log.LogError((object)"Could not locate Valheim's placement rotation code. Axis Rotation will not function.");
			}
			return list;
		}
	}

	public const string PluginGuid = "robit.valheim.advancedhammerrotation";

	public const string PluginName = "Axis Rotation";

	public const string PluginVersion = "1.0.0";

	private Harmony _harmony;

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> EnableCultivatorRotation;

	internal static ConfigEntry<KeyboardShortcut> CycleAxisKey;

	internal static ConfigEntry<KeyboardShortcut> ResetRotationKey;

	internal static ConfigEntry<float> RotationStep;

	private static RotationAxis _currentAxis = RotationAxis.Y;

	private static Quaternion _placementRotation = Quaternion.identity;

	private static readonly FieldInfo RightItemField = AccessTools.Field(typeof(Humanoid), "m_rightItem");

	private static bool IsCultivator(Player player)
	{
		if ((Object)(object)player == (Object)null || RightItemField == null)
		{
			return false;
		}
		object? value = RightItemField.GetValue(player);
		ItemData val = (ItemData)((value is ItemData) ? value : null);
		if (val != null && val.m_shared != null)
		{
			return val.m_shared.m_name == "$item_cultivator";
		}
		return false;
	}

	private static bool RotationEnabledForCurrentTool(Player player)
	{
		if (IsCultivator(player))
		{
			return EnableCultivatorRotation.Value;
		}
		return true;
	}

	private void Awake()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		EnableCultivatorRotation = ((BaseUnityPlugin)this).Config.Bind<bool>("Tools", "Enable Cultivator Rotation", false, "Allows axis rotation while using the cultivator.");
		CycleAxisKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Cycle Axis", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), "Cycles the building rotation axis: Y -> X -> Z -> Y.");
		ResetRotationKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Reset Rotation", new KeyboardShortcut((KeyCode)103, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Resets the placement rotation.");
		RotationStep = ((BaseUnityPlugin)this).Config.Bind<float>("Rotation", "Rotation Step", 22.5f, "Degrees rotated per mouse wheel step. 22.5 is vanilla (11.25 is half).");
		_harmony = new Harmony("robit.valheim.advancedhammerrotation");
		_harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Axis Rotation 1.0.0 loaded.");
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	private static void CycleAxis()
	{
		switch (_currentAxis)
		{
		case RotationAxis.Y:
			_currentAxis = RotationAxis.X;
			break;
		case RotationAxis.X:
			_currentAxis = RotationAxis.Z;
			break;
		default:
			_currentAxis = RotationAxis.Y;
			break;
		}
		ShowMessage($"Rotation Axis: {_currentAxis}");
	}

	private static void ResetRotation()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		_placementRotation = Quaternion.identity;
		_currentAxis = RotationAxis.Y;
		ShowMessage("Rotation Reset - Axis: Y");
	}

	private static void Rotate(int direction)
	{
		//IL_0022: 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_0039: 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_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)
		//IL_0049: 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_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)
		if (direction != 0)
		{
			float num = (float)direction * RotationStep.Value;
			_placementRotation = Quaternion.AngleAxis(num, (Vector3)(_currentAxis switch
			{
				RotationAxis.X => Vector3.right, 
				RotationAxis.Z => Vector3.forward, 
				_ => Vector3.up, 
			})) * _placementRotation;
		}
	}

	private static void ShowMessage(string message)
	{
		if ((Object)(object)MessageHud.instance != (Object)null)
		{
			MessageHud.instance.ShowMessage((MessageType)1, message, 0, (Sprite)null, false, true);
		}
	}

	private static Quaternion GetPlacementRotation(float x, float y, float z)
	{
		//IL_0020: 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)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer != (Object)null && !RotationEnabledForCurrentTool(localPlayer))
		{
			return Quaternion.Euler(x, y, z);
		}
		return _placementRotation;
	}
}