Decompiled source of WiresShakeItUp v0.1.0

WiresShakeItUp.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WiresShakeItUp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WiresShakeItUp")]
[assembly: AssemblyTitle("WiresShakeItUp")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 WiresShakeItUp
{
	internal static class ModConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> OverallStrength;

		internal static ConfigEntry<float> RumbleStrength;

		internal static ConfigEntry<float> ImpactStrength;

		internal static ConfigEntry<float> ImpactDuration;

		internal static ConfigEntry<float> LongShakeSoftening;

		internal static ConfigEntry<float> MaxRumbleDegrees;

		internal static ConfigEntry<float> FrequencyMultiplier;

		internal static ConfigEntry<float> SecondaryMotion;

		internal static ConfigEntry<float> PositionShake;

		internal static ConfigEntry<float> RollStrength;

		internal static ConfigEntry<bool> DirectionalImpact;

		internal static ConfigEntry<float> ImpactThreshold;

		internal static void Bind(ConfigFile file)
		{
			Enabled = file.Bind<bool>("General", "Enabled", true, "Enable Wire's Shake It Up.");
			OverallStrength = Float(file, "General", "Overall Strength", 0.5f, 0f, 2f, "Master multiplier for all Shake It Up camera motion.");
			RumbleStrength = Float(file, "Rumble", "Rumble Strength", 0.85f, 0f, 2f, "Strength of the sustained shake after the initial impact.");
			LongShakeSoftening = Float(file, "Rumble", "Long Shake Softening", 0.8f, 0f, 1f, "How strongly long vanilla shakes are prevented from also becoming absurdly strong. 1 keeps extra duration without adding much extra amplitude.");
			MaxRumbleDegrees = Float(file, "Rumble", "Max Rumble Degrees", 1.25f, 0.1f, 4f, "Approximate cap for the sustained rotational shake before Valheim's own camera movement multiplier.");
			FrequencyMultiplier = Float(file, "Rumble", "Frequency Multiplier", 0.9f, 0.25f, 2f, "Speed of the sustained shake.");
			SecondaryMotion = Float(file, "Rumble", "Secondary Motion", 0.18f, 0f, 1f, "Adds a subtle second motion layer so sustained shake feels less mechanically sinusoidal.");
			PositionShake = Float(file, "Rumble", "Position Shake", 0.018f, 0f, 0.08f, "Small positional camera movement in metres. Set to 0 for rotation-only shake.");
			ImpactStrength = Float(file, "Impact", "Impact Strength", 1f, 0f, 2f, "Strength of the short punch at the start of a new shake.");
			ImpactDuration = Float(file, "Impact", "Impact Duration", 0.18f, 0.05f, 0.5f, "Length in seconds of the initial impact kick.");
			ImpactThreshold = Float(file, "Impact", "Impact Threshold", 0.12f, 0f, 1f, "Very tiny shakes below this effective strength do not get an extra impact kick.");
			DirectionalImpact = file.Bind<bool>("Impact", "Directional Impact", true, "Bias the initial kick away from the shake source.");
			RollStrength = Float(file, "Impact", "Roll Strength", 0f, 0f, 1f, "Camera roll added to impacts. Default is 0 to avoid nausea.");
			Hook<bool>(Enabled);
			Hook<float>(OverallStrength);
			Hook<float>(RumbleStrength);
			Hook<float>(ImpactStrength);
			Hook<float>(ImpactDuration);
			Hook<float>(LongShakeSoftening);
			Hook<float>(MaxRumbleDegrees);
			Hook<float>(FrequencyMultiplier);
			Hook<float>(SecondaryMotion);
			Hook<float>(PositionShake);
			Hook<float>(RollStrength);
			Hook<bool>(DirectionalImpact);
			Hook<float>(ImpactThreshold);
		}

		private static ConfigEntry<float> Float(ConfigFile file, string section, string key, float value, float min, float max, string description)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return file.Bind<float>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
		}

		private static void Hook<T>(ConfigEntry<T> entry)
		{
			entry.SettingChanged += delegate
			{
				ShakeEngine.ResetTransient();
			};
		}
	}
	[HarmonyPatch(typeof(GameCamera), "Awake")]
	internal static class GameCameraAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			ShakeEngine.ResetTransient();
		}
	}
	[HarmonyPatch(typeof(GameCamera), "GetAttenuatedShakeIntensity")]
	internal static class ShakeAmplitudePatch
	{
		[HarmonyPostfix]
		private static void Postfix(GameCamera __instance, ref float __result)
		{
			__result = ShakeEngine.ShapeRumble(__instance, __result);
		}
	}
	[HarmonyPatch(typeof(GameCamera), "AddShake")]
	internal static class AddShakePatch
	{
		[HarmonyPrefix]
		private static void Prefix(GameCamera __instance, out float __state)
		{
			__state = ShakeEngine.CurrentIntensity(__instance);
		}

		[HarmonyPostfix]
		private static void Postfix(GameCamera __instance, Vector3 point, float range, float strength, float __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ShakeEngine.ObserveShake(__instance, point, range, strength, __state);
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateCameraShake")]
	internal static class UpdateCameraShakePatch
	{
		[HarmonyPrefix]
		private static void Prefix(GameCamera __instance, out float __state)
		{
			__state = __instance.m_shakeFreq;
			if (ShakeEngine.Enabled(__instance))
			{
				__instance.m_shakeFreq = __state * ModConfig.FrequencyMultiplier.Value;
			}
		}

		[HarmonyPostfix]
		private static void Postfix(GameCamera __instance, float dt, float __state)
		{
			try
			{
				ShakeEngine.AfterCameraShake(__instance, dt);
			}
			finally
			{
				__instance.m_shakeFreq = __state;
			}
		}
	}
	[BepInPlugin("wire.valheim.shakeitup", "Wire's Shake It Up", "0.1.0")]
	[BepInProcess("valheim.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "wire.valheim.shakeitup";

		public const string Name = "Wire's Shake It Up";

		public const string Version = "0.1.0";

		internal static Plugin Instance;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Instance = this;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("wire.valheim.shakeitup");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Wire's Shake It Up 0.1.0 loaded.");
		}

		private void OnDestroy()
		{
			ShakeEngine.Reset();
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
			Instance = null;
		}
	}
	internal static class ShakeEngine
	{
		private static readonly FieldRef<GameCamera, float> ShakeIntensity = AccessTools.FieldRefAccess<GameCamera, float>("m_shakeIntensity");

		private static readonly FieldRef<GameCamera, bool> CameraShakeEnabled = AccessTools.FieldRefAccess<GameCamera, bool>("m_cameraShakeEnabled");

		private static float _phase;

		private static float _kickRemaining;

		private static float _kickDuration;

		private static float _kickPitch;

		private static float _kickYaw;

		private static float _kickRoll;

		private static float _lastAcceptedCall = -999f;

		private static float _lastImpactTime = -999f;

		private static Vector3 _lastSource;

		private static bool _hasLastSource;

		internal static float CurrentIntensity(GameCamera camera)
		{
			if (!((Object)(object)camera == (Object)null))
			{
				return ShakeIntensity.Invoke(camera);
			}
			return 0f;
		}

		internal static bool IsCameraShakeEnabled(GameCamera camera)
		{
			if ((Object)(object)camera != (Object)null)
			{
				return CameraShakeEnabled.Invoke(camera);
			}
			return false;
		}

		internal static float ShapeRumble(GameCamera camera, float vanillaAmplitude)
		{
			if (!Enabled(camera))
			{
				return vanillaAmplitude;
			}
			float num = Mathf.Max(0f, CurrentIntensity(camera));
			if (num <= 0f)
			{
				return 0f;
			}
			float num2;
			if (num <= 1f)
			{
				num2 = num * num * num;
			}
			else
			{
				float value = ModConfig.LongShakeSoftening.Value;
				num2 = 1f + (num - 1f) * (1f - value);
				num2 = Mathf.Min(num2, ModConfig.MaxRumbleDegrees.Value);
			}
			return num2 * ModConfig.RumbleStrength.Value * ModConfig.OverallStrength.Value;
		}

		internal static void ObserveShake(GameCamera camera, Vector3 point, float range, float strength, float previousIntensity)
		{
			//IL_0011: 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_0076: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled(camera) || range <= 0f)
			{
				return;
			}
			float num = Vector3.Distance(point, ((Component)camera).transform.position);
			if (num > range)
			{
				return;
			}
			num = Mathf.Max(1f, num);
			float num2 = strength * (1f - num / range);
			if (!(num2 < ModConfig.ImpactThreshold.Value) && !(num2 + 0.0001f < previousIntensity))
			{
				float unscaledTime = Time.unscaledTime;
				bool flag = unscaledTime - _lastAcceptedCall > 0.16f;
				int num3;
				if (_hasLastSource)
				{
					Vector3 val = point - _lastSource;
					num3 = ((((Vector3)(ref val)).sqrMagnitude > 4f) ? 1 : 0);
				}
				else
				{
					num3 = 1;
				}
				bool flag2 = (byte)num3 != 0;
				bool flag3 = num2 > previousIntensity + Mathf.Max(0.08f, previousIntensity * 0.12f);
				if (unscaledTime - _lastImpactTime > 0.075f && (flag || flag2 || flag3))
				{
					StartImpact(camera, point, num2, unscaledTime);
				}
				_lastAcceptedCall = unscaledTime;
				_lastSource = point;
				_hasLastSource = true;
			}
		}

		private static void StartImpact(GameCamera camera, Vector3 point, float effective, float now)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(0.15f + 0.55f * Mathf.Sqrt(Mathf.Max(0f, effective)), 0f, 1.2f);
			num *= ModConfig.ImpactStrength.Value * ModConfig.OverallStrength.Value;
			_kickDuration = ModConfig.ImpactDuration.Value;
			_kickRemaining = _kickDuration;
			Vector3 val = point - ((Component)camera).transform.position;
			Vector3 val2 = Vector3.zero;
			if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				val2 = ((Component)camera).transform.InverseTransformDirection(((Vector3)(ref val)).normalized);
			}
			float num2 = ((Mathf.Sin(point.x * 12.9898f + point.z * 78.233f + now * 3.173f) >= 0f) ? 1f : (-1f));
			if (ModConfig.DirectionalImpact.Value)
			{
				_kickYaw = num * ((0f - val2.x) * 0.55f + num2 * 0.12f);
				_kickPitch = (0f - num) * (0.68f - val2.y * 0.16f);
			}
			else
			{
				_kickYaw = num2 * num * 0.32f;
				_kickPitch = (0f - num) * 0.68f;
			}
			_kickRoll = num2 * num * 0.18f * ModConfig.RollStrength.Value;
			_lastImpactTime = now;
		}

		internal static void AfterCameraShake(GameCamera camera, float dt)
		{
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled(camera))
			{
				return;
			}
			if (!IsCameraShakeEnabled(camera))
			{
				_kickRemaining = 0f;
				return;
			}
			float num = Mathf.Max(0f, CurrentIntensity(camera));
			float num2 = ShapeRumble(camera, 0f) * camera.m_shakeMovement;
			float num3 = Mathf.InverseLerp(1f, 3f, num);
			float num4 = Mathf.Lerp(1.08f, 0.72f, num3);
			_phase += dt * camera.m_shakeFreq * num4;
			float num5 = num2 * ModConfig.SecondaryMotion.Value;
			float num6 = Mathf.Sin(_phase * 1.73f + 0.4f) * num5 * 0.42f;
			float num7 = Mathf.Cos(_phase * 1.37f + 1.1f) * num5 * 0.35f;
			float num8 = Mathf.Sin(_phase * 0.91f + 2.2f) * num5 * 0.08f * ModConfig.RollStrength.Value;
			if (_kickRemaining > 0f && _kickDuration > 0f)
			{
				float num9 = Mathf.Clamp01(_kickRemaining / _kickDuration);
				float num10 = num9 * num9 * (3f - 2f * num9);
				num6 += _kickPitch * num10;
				num7 += _kickYaw * num10;
				num8 += _kickRoll * num10;
				_kickRemaining = Mathf.Max(0f, _kickRemaining - dt);
			}
			if (Mathf.Abs(num6) > 0.0001f || Mathf.Abs(num7) > 0.0001f || Mathf.Abs(num8) > 0.0001f)
			{
				((Component)camera).transform.rotation = ((Component)camera).transform.rotation * Quaternion.Euler(num6, num7, num8);
			}
			float num11 = ModConfig.PositionShake.Value * ModConfig.OverallStrength.Value * Mathf.Clamp01(num2);
			if (num11 > 1E-05f)
			{
				Vector3 val = ((Component)camera).transform.right * (Mathf.Sin(_phase * 0.83f + 0.2f) * num11) + ((Component)camera).transform.up * (Mathf.Cos(_phase * 1.11f + 1.7f) * num11 * 0.55f);
				Transform transform = ((Component)camera).transform;
				transform.position += val;
			}
		}

		internal static bool Enabled(GameCamera camera)
		{
			if ((Object)(object)camera != (Object)null && ModConfig.Enabled != null)
			{
				return ModConfig.Enabled.Value;
			}
			return false;
		}

		internal static void ResetTransient()
		{
			//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)
			_phase = 0f;
			_kickRemaining = 0f;
			_kickDuration = 0f;
			_kickPitch = 0f;
			_kickYaw = 0f;
			_kickRoll = 0f;
			_lastAcceptedCall = -999f;
			_lastImpactTime = -999f;
			_lastSource = Vector3.zero;
			_hasLastSource = false;
		}

		internal static void Reset()
		{
			ResetTransient();
		}
	}
}