Decompiled source of BuildCamera Ymiron v1.0.2

BuildCamera.dll

Decompiled 15 hours ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BuildCamera")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("BuildCamera")]
[assembly: AssemblyTitle("BuildCamera")]
[assembly: AssemblyVersion("1.0.2.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 BuildCamera
{
	internal static class BuildCam
	{
		private const float GroundClearance = 0.5f;

		private static Vector3 _position;

		private static float _yaw;

		private static float _pitch;

		internal static bool Active { get; private set; }

		internal static void Update()
		{
			Player localPlayer = Player.m_localPlayer;
			if (Active && !CanStay(localPlayer))
			{
				Exit(null);
			}
			else if (TogglePressed())
			{
				if (Active)
				{
					Exit("Build camera off");
				}
				else
				{
					TryEnter(localPlayer);
				}
			}
		}

		private static void TryEnter(Player player)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			if (!((Object)(object)player == (Object)null) && !((Object)(object)GameCamera.instance == (Object)null) && !GameCamera.InFreeFly())
			{
				if (!((Character)player).InPlaceMode())
				{
					Message(player, "Equip the hammer to use the build camera");
				}
				else if (CanStay(player))
				{
					Transform transform = ((Component)GameCamera.instance).transform;
					_position = transform.position;
					Quaternion rotation = transform.rotation;
					Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
					_yaw = eulerAngles.y;
					_pitch = Mathf.Clamp((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x, -89f, 89f);
					Active = true;
					Message(player, "Build camera on");
				}
			}
		}

		internal static void Exit(string message)
		{
			if (Active)
			{
				Active = false;
				if (message != null)
				{
					Message(Player.m_localPlayer, message);
				}
			}
		}

		private static bool CanStay(Player player)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)GameCamera.instance != (Object)null && !GameCamera.InFreeFly() && ((Character)player).InPlaceMode() && !((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).IsAttached())
			{
				return !((Character)player).InCutscene();
			}
			return false;
		}

		internal static void Drive(GameCamera gameCamera, float dt)
		{
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: 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)
			//IL_0024: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (InputFree())
			{
				Vector2 val = ZInput.GetMouseDelta() * PlayerController.m_mouseSens * ModConfig.MouseSensitivity.Value;
				if (PlayerController.m_invertMouse)
				{
					val.y = 0f - val.y;
				}
				_yaw = Mathf.Repeat(_yaw + val.x, 360f);
				_pitch = Mathf.Clamp(_pitch - val.y, -89f, 89f);
				Vector3 zero = Vector3.zero;
				if (ZInput.GetButton("Forward"))
				{
					zero.z += 1f;
				}
				if (ZInput.GetButton("Backward"))
				{
					zero.z -= 1f;
				}
				if (ZInput.GetButton("Right"))
				{
					zero.x += 1f;
				}
				if (ZInput.GetButton("Left"))
				{
					zero.x -= 1f;
				}
				if (ZInput.GetButton("Jump"))
				{
					zero.y += 1f;
				}
				if (ZInput.GetButton("Crouch"))
				{
					zero.y -= 1f;
				}
				if (((Vector3)(ref zero)).sqrMagnitude > 1f)
				{
					((Vector3)(ref zero)).Normalize();
				}
				float num = ModConfig.Speed.Value;
				if (ZInput.GetButton("Run"))
				{
					num *= ModConfig.FastMultiplier.Value;
				}
				Vector3 val2 = (ModConfig.FlatMovement.Value ? Quaternion.Euler(0f, _yaw, 0f) : Quaternion.Euler(_pitch, _yaw, 0f)) * new Vector3(zero.x, 0f, zero.z);
				_position += (val2 + Vector3.up * zero.y) * (num * dt);
			}
			ClampPosition(localPlayer);
			Transform transform = ((Component)gameCamera).transform;
			transform.position = _position;
			transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f);
			Camera component = ((Component)gameCamera).GetComponent<Camera>();
			if ((Object)(object)component != (Object)null && component.nearClipPlane != gameCamera.m_nearClipPlaneMin)
			{
				component.nearClipPlane = gameCamera.m_nearClipPlaneMin;
			}
		}

		private static void ClampPosition(Player player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Character)player).m_eye.position;
			Vector3 val = _position - position;
			float value = ModConfig.MaxDistance.Value;
			if (((Vector3)(ref val)).sqrMagnitude > value * value)
			{
				_position = position + ((Vector3)(ref val)).normalized * value;
			}
			float num = default(float);
			if (ModConfig.StayAboveGround.Value && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(_position, ref num) && _position.y < num + 0.5f)
			{
				_position.y = num + 0.5f;
			}
		}

		private static bool InputFree()
		{
			if (((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !StoreGui.IsVisible() && !Hud.IsPieceSelectionVisible() && !Hud.InRadial())
			{
				if (!((Object)(object)Hud.instance == (Object)null))
				{
					return !Hud.instance.m_buildUi.SearchFieldFocused;
				}
				return true;
			}
			return false;
		}

		private static bool TogglePressed()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			KeyboardShortcut value = ModConfig.ToggleKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false))
			{
				return false;
			}
			if (((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible() || ((Object)(object)Hud.instance != (Object)null && Hud.instance.m_buildUi.SearchFieldFocused))
			{
				return false;
			}
			return ((KeyboardShortcut)(ref value)).Modifiers.All(Held);
		}

		private static bool Held(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected I4, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			switch (key - 303)
			{
			case 0:
			case 1:
				if (!ZInput.GetKey((KeyCode)304, false))
				{
					return ZInput.GetKey((KeyCode)303, false);
				}
				return true;
			case 2:
			case 3:
				if (!ZInput.GetKey((KeyCode)306, false))
				{
					return ZInput.GetKey((KeyCode)305, false);
				}
				return true;
			case 4:
			case 5:
				if (!ZInput.GetKey((KeyCode)308, false))
				{
					return ZInput.GetKey((KeyCode)307, false);
				}
				return true;
			default:
				return ZInput.GetKey(key, false);
			}
		}

		private static void Message(Player player, string text)
		{
			if ((Object)(object)player != (Object)null)
			{
				((Character)player).Message((MessageType)1, text, 0, (Sprite)null, false);
			}
		}
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<float> Speed;

		internal static ConfigEntry<float> FastMultiplier;

		internal static ConfigEntry<float> MouseSensitivity;

		internal static ConfigEntry<bool> FlatMovement;

		internal static ConfigEntry<float> MaxDistance;

		internal static ConfigEntry<float> PlaceReach;

		internal static ConfigEntry<bool> StayAboveGround;

		internal static ConfigEntry<bool> StationNearPiece;

		internal static ConfigEntry<bool> ExitOnDamage;

		internal static void Bind(ConfigFile cfg)
		{
			//IL_0012: 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_0059: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			ToggleKey = cfg.Bind<KeyboardShortcut>("1 - Keys", "Toggle", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Detaches the camera from your character (you must be holding a building tool: hammer, hoe or cultivator); press it again to reattach. Modifiers are allowed, e.g. \"B + LeftAlt\".");
			Speed = cfg.Bind<float>("2 - Movement", "Speed", 10f, new ConfigDescription("Camera speed in meters per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>()));
			FastMultiplier = cfg.Bind<float>("2 - Movement", "RunMultiplier", 3f, new ConfigDescription("Holding the run key (Shift) makes the camera faster by this factor.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			MouseSensitivity = cfg.Bind<float>("2 - Movement", "MouseSensitivity", 1f, new ConfigDescription("Multiplies the mouse sensitivity set in the game options.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			FlatMovement = cfg.Bind<bool>("2 - Movement", "HorizontalMovement", true, "true = forward/backward stay horizontal even when looking up or down; you only go up and down with Jump and Crouch. false = the camera flies where you look, like the game's free camera.");
			MaxDistance = cfg.Bind<float>("3 - Limits", "MaxDistance", 40f, new ConfigDescription("How far (in meters) the camera can move away from your character.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>()));
			PlaceReach = cfg.Bind<float>("3 - Limits", "PlacementReach", 10f, new ConfigDescription("Up to what distance from the camera (in meters) you can place, repair and remove pieces. In the normal game the limit is 5 m from your character.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 50f), Array.Empty<object>()));
			StayAboveGround = cfg.Bind<bool>("3 - Limits", "StayAboveGround", true, "true = the camera cannot go below the terrain. Walls and pieces can still be passed through.");
			StationNearPiece = cfg.Bind<bool>("3 - Limits", "WorkbenchNearPiece", true, "true = the workbench (or forge, etc.) must be near the piece you place or remove, not near your character: the camera can't be used to build far away from your base. false = only your character's position counts, as in the normal game.");
			ExitOnDamage = cfg.Bind<bool>("3 - Limits", "ExitWhenHit", true, "true = if your character takes damage the camera snaps back to them.");
		}
	}
	internal static class Reach
	{
		private const float Unlimited = 1000f;

		private static readonly FieldRef<Player, int> PlaceRayMask = AccessTools.FieldRefAccess<Player, int>("m_placeRayMask");

		private static readonly FieldRef<Player, int> PlaceWaterRayMask = AccessTools.FieldRefAccess<Player, int>("m_placeWaterRayMask");

		private static readonly FieldRef<Player, int> RemoveRayMask = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask");

		internal static readonly FieldRef<Player, GameObject> PlacementGhost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		internal static readonly FieldRef<Player, Piece> HoveringPiece = AccessTools.FieldRefAccess<Player, Piece>("m_hoveringPiece");

		internal static bool Applies(Player player)
		{
			if (BuildCam.Active && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer)
			{
				return (Object)(object)GameCamera.instance != (Object)null;
			}
			return false;
		}

		internal static int PlaceMask(Player player, bool water)
		{
			if (!water)
			{
				return PlaceRayMask.Invoke(player);
			}
			return PlaceWaterRayMask.Invoke(player);
		}

		internal static int RemoveMask(Player player)
		{
			return RemoveRayMask.Invoke(player);
		}

		internal static bool CameraHitWithin(int mask, float reach)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)GameCamera.instance).transform;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(transform.position, transform.forward, ref val, 50f, mask))
			{
				return ((RaycastHit)(ref val)).distance <= reach;
			}
			return false;
		}

		internal static float Lift(Player player)
		{
			float maxPlaceDistance = player.m_maxPlaceDistance;
			player.m_maxPlaceDistance = 1000f;
			return maxPlaceDistance;
		}

		internal static void Restore(Player player, float saved)
		{
			if (saved >= 0f)
			{
				player.m_maxPlaceDistance = saved;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "PieceRayTest")]
	internal static class PieceRayTestPatch
	{
		private static bool Prefix(Player __instance, bool water, ref Vector3 point, ref Vector3 normal, ref Piece piece, ref Heightmap heightmap, ref Collider waterSurface, ref bool __result, out float __state)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			__state = -1f;
			if (!Reach.Applies(__instance))
			{
				return true;
			}
			float num = ModConfig.PlaceReach.Value;
			GameObject val = Reach.PlacementGhost.Invoke(__instance);
			Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				num += (float)val2.m_extraPlacementDistance;
			}
			if (!Reach.CameraHitWithin(Reach.PlaceMask(__instance, water), num))
			{
				point = Vector3.zero;
				normal = Vector3.zero;
				piece = null;
				heightmap = null;
				waterSurface = null;
				__result = false;
				return false;
			}
			__state = Reach.Lift(__instance);
			return true;
		}

		private static void Finalizer(Player __instance, float __state)
		{
			Reach.Restore(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateWearNTearHover")]
	internal static class WearNTearHoverPatch
	{
		private static bool Prefix(Player __instance, out float __state)
		{
			__state = -1f;
			if (!Reach.Applies(__instance) || !((Character)__instance).InPlaceMode())
			{
				return true;
			}
			if (!Reach.CameraHitWithin(Reach.RemoveMask(__instance), ModConfig.PlaceReach.Value))
			{
				Reach.HoveringPiece.Invoke(__instance) = null;
				return false;
			}
			__state = Reach.Lift(__instance);
			return true;
		}

		private static void Finalizer(Player __instance, float __state)
		{
			Reach.Restore(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Player), "RemovePiece")]
	internal static class RemovePiecePatch
	{
		private static bool Prefix(Player __instance, ref bool __result, out float __state)
		{
			__state = -1f;
			if (!Reach.Applies(__instance))
			{
				return true;
			}
			if (!Reach.CameraHitWithin(Reach.RemoveMask(__instance), ModConfig.PlaceReach.Value))
			{
				__result = false;
				return false;
			}
			__state = Reach.Lift(__instance);
			return true;
		}

		private static void Finalizer(Player __instance, float __state)
		{
			Reach.Restore(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Player), "CopyPiece")]
	internal static class CopyPiecePatch
	{
		private static bool Prefix(Player __instance, ref bool __result, out float __state)
		{
			__state = -1f;
			if (!Reach.Applies(__instance))
			{
				return true;
			}
			if (!Reach.CameraHitWithin(Reach.RemoveMask(__instance), ModConfig.PlaceReach.Value))
			{
				__result = false;
				return false;
			}
			__state = Reach.Lift(__instance);
			return true;
		}

		private static void Finalizer(Player __instance, float __state)
		{
			Reach.Restore(__instance, __state);
		}
	}
	internal static class Station
	{
		internal static Vector3? Point;

		internal static bool Applies(Player player)
		{
			if (Reach.Applies(player))
			{
				return ModConfig.StationNearPiece.Value;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	internal static class HaveRequirementsPatch
	{
		private static void Prefix(Player __instance, RequirementMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((int)mode == 0 && Station.Applies(__instance))
			{
				GameObject val = Reach.PlacementGhost.Invoke(__instance);
				if ((Object)(object)val != (Object)null)
				{
					Station.Point = val.transform.position;
				}
			}
		}

		private static void Finalizer()
		{
			Station.Point = null;
		}
	}
	[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
	internal static class CheckCanRemovePiecePatch
	{
		private static void Prefix(Player __instance, Piece piece)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)piece != (Object)null && Station.Applies(__instance))
			{
				Station.Point = ((Component)piece).transform.position;
			}
		}

		private static void Finalizer()
		{
			Station.Point = null;
		}
	}
	[HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")]
	internal static class HaveBuildStationInRangePatch
	{
		private static void Prefix(ref Vector3 point)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (Station.Point.HasValue)
			{
				point = Station.Point.Value;
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
	internal static class UpdateCameraPatch
	{
		private static bool Prefix(GameCamera __instance, float dt)
		{
			if (!BuildCam.Active)
			{
				return true;
			}
			BuildCam.Drive(__instance, dt);
			return false;
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateListner")]
	internal static class UpdateListenerPatch
	{
		private static readonly FieldRef<GameCamera, AudioListener> Listener = AccessTools.FieldRefAccess<GameCamera, AudioListener>("m_listner");

		private static bool Prefix(GameCamera __instance)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!BuildCam.Active)
			{
				return true;
			}
			AudioListener val = Listener.Invoke(__instance);
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).transform.localPosition = Vector3.zero;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
	internal static class PlayerControllerFixedUpdatePatch
	{
		private static readonly FieldRef<float> TakeInputDelay = AccessTools.StaticFieldRefAccess<float>(AccessTools.Field(typeof(PlayerController), "takeInputDelay"));

		private static bool Prefix(PlayerController __instance)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!BuildCam.Active)
			{
				return true;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			TakeInputDelay.Invoke() = Mathf.Max(0f, TakeInputDelay.Invoke() - Time.deltaTime);
			component.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false);
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerController), "LateUpdate")]
	internal static class PlayerControllerLateUpdatePatch
	{
		private static bool Prefix(PlayerController __instance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!BuildCam.Active)
			{
				return true;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			component.SetMouseLook(Vector2.zero);
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "OnDamaged")]
	internal static class OnDamagedPatch
	{
		private static void Postfix(Player __instance)
		{
			if (BuildCam.Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && ModConfig.ExitOnDamage.Value)
			{
				BuildCam.Exit("You were hit: camera back to your character");
			}
		}
	}
	[BepInPlugin("ymiron.valheim.buildcamera", "BuildCamera-Ymiron", "1.0.2")]
	[BepInProcess("valheim.exe")]
	public class BuildCameraPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "ymiron.valheim.buildcamera";

		public const string PluginName = "BuildCamera-Ymiron";

		public const string PluginVersion = "1.0.2";

		private Harmony _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("ymiron.valheim.buildcamera");
			_harmony.PatchAll(typeof(BuildCameraPlugin).Assembly);
			Log.LogInfo((object)"BuildCamera-Ymiron 1.0.2 loaded.");
		}

		private void Update()
		{
			BuildCam.Update();
		}

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