Decompiled source of Memories v1.1.0

Memories.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Memories")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Riintouge")]
[assembly: AssemblyProduct("Memories")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8feb5558-d229-48a5-b282-45680131f27d")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace Memories;

[BepInPlugin("com.riintouge.memories", "Memories", "1.1.0")]
[BepInProcess("valheim.exe")]
public class Memories : BaseUnityPlugin
{
	[HarmonyPatch(typeof(GameCamera))]
	private class GameCameraPatch
	{
		public enum CameraContext
		{
			Generic,
			Saddle,
			Ship
		}

		private const float HalfPI = (float)Math.PI / 2f;

		private static CameraContext LastCameraContext = CameraContext.Generic;

		private static float FrameInitialCameraDistance = 4f;

		private static InterpolationTypeEnum LerpType = InterpolationTypeEnum.Immediate;

		private static float LerpFrom = 4f;

		private static float LerpTo = 4f;

		private static float LerpElapsed = 0f;

		private static float LerpDuration = 0f;

		private static float LerpDistanceOverride = 4f;

		private static bool IsInterpolating = false;

		private static CameraContext GetCameraContext(Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				if ((Object)(object)player.GetControlledShip() != (Object)null)
				{
					return CameraContext.Ship;
				}
				if (((Character)player).IsRiding())
				{
					return CameraContext.Saddle;
				}
			}
			return CameraContext.Generic;
		}

		private static void UpdateCameraCore(CameraContext context, ref float targetZoom, ref float ___m_distance, float ___m_minDistance, float ___m_maxDistance)
		{
			if (LastCameraContext != context)
			{
				if (InterpolationType.Value != 0 && InterpolationDuration.Value > 0f)
				{
					LerpType = InterpolationType.Value;
					LerpFrom = FrameInitialCameraDistance;
					LerpTo = targetZoom;
					LerpElapsed = 0f;
					LerpDuration = Mathf.Max(0f, InterpolationDuration.Value);
					LerpDistanceOverride = FrameInitialCameraDistance;
					IsInterpolating = true;
				}
				else
				{
					___m_distance = Mathf.Clamp(targetZoom, ___m_minDistance, ___m_maxDistance);
				}
			}
			else if (!IsInterpolating && targetZoom != ___m_distance)
			{
				targetZoom = Mathf.Clamp(___m_distance, ___m_minDistance, ___m_maxDistance);
			}
		}

		[HarmonyPatch("ApplySettings")]
		[HarmonyPrefix]
		private static void ApplySettingsPrefix(ref float ___m_distance, ref float ___m_minDistance, ref float ___m_maxDistance, ref float ___m_maxDistanceBoat)
		{
			if (IsEnabled.Value)
			{
				LastCameraContext = GetCameraContext(Player.m_localPlayer);
				if (LastCameraContext == CameraContext.Saddle)
				{
					___m_distance = Mathf.Clamp(LastSaddleZoom, ___m_minDistance, ___m_maxDistance);
				}
				else if (LastCameraContext == CameraContext.Ship)
				{
					___m_distance = Mathf.Clamp(LastShipZoom, ___m_minDistance, ___m_maxDistanceBoat);
				}
				else
				{
					___m_distance = Mathf.Clamp(LastCameraZoom, ___m_minDistance, ___m_maxDistance);
				}
			}
		}

		[HarmonyPatch("GetCameraPosition")]
		[HarmonyPrefix]
		private static void GetCameraPositionPrefix(ref float ___m_distance)
		{
			if (IsEnabled.Value)
			{
				if (IsInterpolating)
				{
					___m_distance = LerpDistanceOverride;
				}
				else if (LastCameraContext != GetCameraContext(Player.m_localPlayer))
				{
					___m_distance = FrameInitialCameraDistance;
				}
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPrefix(ref float ___m_distance)
		{
			IsInterpolating = false;
			LerpFrom = 4f;
			LerpTo = 4f;
			LerpElapsed = 0f;
			LerpDistanceOverride = 4f;
			FrameInitialCameraDistance = 4f;
			LastCameraContext = CameraContext.Generic;
		}

		[HarmonyPatch("UpdateCamera")]
		[HarmonyPrefix]
		private static void UpdateCameraPrefix(ref float ___m_distance)
		{
			FrameInitialCameraDistance = ___m_distance;
		}

		[HarmonyPatch("UpdateCamera")]
		[HarmonyPostfix]
		private static void UpdateCameraPostfix(ref float dt, ref float ___m_distance, ref float ___m_minDistance, ref float ___m_maxDistance, ref float ___m_maxDistanceBoat)
		{
			if (!IsEnabled.Value)
			{
				return;
			}
			if (IsInterpolating)
			{
				LerpElapsed = Mathf.Clamp(LerpElapsed + dt, 0f, LerpDuration);
				float num = LerpElapsed / LerpDuration;
				if (LerpType == InterpolationTypeEnum.Linear)
				{
					___m_distance = Mathf.Lerp(LerpFrom, LerpTo, num);
				}
				else if (LerpType == InterpolationTypeEnum.Accelerate)
				{
					___m_distance = Mathf.Lerp(LerpFrom, LerpTo, 1f - Mathf.Cos((float)Math.PI / 2f * num));
				}
				else if (LerpType == InterpolationTypeEnum.Decelerate)
				{
					___m_distance = Mathf.Lerp(LerpFrom, LerpTo, Mathf.Sin((float)Math.PI / 2f * num));
				}
				LerpDistanceOverride = ___m_distance;
				IsInterpolating = LerpElapsed < LerpDuration;
			}
			CameraContext cameraContext = GetCameraContext(Player.m_localPlayer);
			switch (cameraContext)
			{
			case CameraContext.Saddle:
				UpdateCameraCore(cameraContext, ref LastSaddleZoom, ref ___m_distance, ___m_minDistance, ___m_maxDistance);
				break;
			case CameraContext.Ship:
				UpdateCameraCore(cameraContext, ref LastShipZoom, ref ___m_distance, ___m_minDistance, ___m_maxDistanceBoat);
				break;
			default:
				UpdateCameraCore(cameraContext, ref LastCameraZoom, ref ___m_distance, ___m_minDistance, ___m_maxDistance);
				break;
			}
			LastCameraContext = cameraContext;
		}
	}

	public enum InterpolationTypeEnum
	{
		Immediate,
		Linear,
		Accelerate,
		Decelerate
	}

	public const float VanillaDefaultZoom = 4f;

	public static ConfigEntry<bool> IsEnabled;

	public static ConfigEntry<bool> LoadOnStart;

	public static ConfigEntry<float> CameraZoom;

	public static float LastCameraZoom;

	public static ConfigEntry<float> ShipZoom;

	public static float LastShipZoom;

	public static ConfigEntry<float> SaddleZoom;

	public static float LastSaddleZoom;

	public static ConfigEntry<float> InterpolationDuration;

	public static ConfigEntry<InterpolationTypeEnum> InterpolationType;

	private readonly Harmony Harmony = new Harmony("com.riintouge.memories");

	private void Awake()
	{
		IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "Enable", true, "Whether this plugin has any effect when loaded.");
		LoadOnStart = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "LoadOnStart", true, "Whether this plugin loads on game start.");
		CameraZoom = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "CameraZoom", 4f, "Normal camera distance. This value is not updated in real-time to avoid frivolous disk I/O.");
		SaddleZoom = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "SaddleCameraZoom", 4f, "Saddle camera distance. This value is not updated in real-time to avoid frivolous disk I/O.");
		ShipZoom = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "ShipCameraZoom", 4f, "Ship camera distance. This value is not updated in real-time to avoid frivolous disk I/O.");
		InterpolationDuration = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Interpolation", "InterpolationDuration", 1.5f, "How long it takes the camera to reposition, in seconds.");
		InterpolationType = ((BaseUnityPlugin)this).Config.Bind<InterpolationTypeEnum>("2 - Interpolation", "InterpolationType", InterpolationTypeEnum.Decelerate, "How the camera moves when repositioning.");
		if (LoadOnStart.Value)
		{
			Harmony.PatchAll();
			LastCameraZoom = CameraZoom.Value;
			LastSaddleZoom = SaddleZoom.Value;
			LastShipZoom = ShipZoom.Value;
			((BaseUnityPlugin)this).Config.SettingChanged += Config_SettingChanged;
		}
	}

	private void OnDestroy()
	{
		((BaseUnityPlugin)this).Config.SettingChanged -= Config_SettingChanged;
		CameraZoom.Value = LastCameraZoom;
		SaddleZoom.Value = LastSaddleZoom;
		ShipZoom.Value = LastShipZoom;
		Harmony.UnpatchSelf();
	}

	private void Config_SettingChanged(object sender, SettingChangedEventArgs e)
	{
		if (e.ChangedSetting == InterpolationDuration)
		{
			if (InterpolationDuration.Value < 0f)
			{
				InterpolationDuration.Value = 0f;
			}
			else if (InterpolationDuration.Value > 5f)
			{
				InterpolationDuration.Value = 5f;
			}
		}
		else if (e.ChangedSetting == CameraZoom)
		{
			CameraZoom.Value = LastCameraZoom;
		}
		else if (e.ChangedSetting == SaddleZoom)
		{
			SaddleZoom.Value = LastSaddleZoom;
		}
		else if (e.ChangedSetting == ShipZoom)
		{
			ShipZoom.Value = LastShipZoom;
		}
	}
}