Decompiled source of Wide Angle Camera v3.0.0

WideAngleCamera/wk.barackobusiness.wideangle.dll

Decompiled a week ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using DarkMachine.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[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("wk.barackobusiness.wideangle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.2.0")]
[assembly: AssemblyInformationalVersion("2.0.2+59505404541099062ce114e584b0aed33ad88d7d")]
[assembly: AssemblyProduct("Wide Angle Camera")]
[assembly: AssemblyTitle("wk.barackobusiness.wideangle")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 WideAngleCamera
{
	public class CameraManager : MonoBehaviour
	{
		public static CameraManager Instance;

		public static CameraManager HandInstance;

		private Camera front;

		private Camera back;

		private Camera right;

		private Camera left;

		private Camera up;

		private Camera down;

		private RenderTexture cubemap;

		private Material screen;

		private float curFOV;

		private float sprintFOV;

		private ENT_Player player;

		private GameSettings settings;

		private FieldInfo sliding;

		public float FOV
		{
			get
			{
				return screen.GetFloat("_FOV");
			}
			internal set
			{
				screen.SetFloat("_FOV", value);
			}
		}

		internal void Init(Material projector, Camera orig, bool useBack, int size)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			player = ENT_Player.GetPlayer();
			settings = SettingsManager.settings;
			curFOV = settings.playerFOV;
			sprintFOV = curFOV + 15f;
			sliding = typeof(ENT_Player).GetField("isSliding", BindingFlags.Instance | BindingFlags.NonPublic);
			front = ((Component)((Component)this).transform.Find("Front")).GetComponent<Camera>();
			back = ((Component)((Component)this).transform.Find("Back")).GetComponent<Camera>();
			left = ((Component)((Component)this).transform.Find("Left")).GetComponent<Camera>();
			right = ((Component)((Component)this).transform.Find("Right")).GetComponent<Camera>();
			up = ((Component)((Component)this).transform.Find("Up")).GetComponent<Camera>();
			down = ((Component)((Component)this).transform.Find("Down")).GetComponent<Camera>();
			((Component)back).gameObject.SetActive(useBack);
			SetupCams(orig, size);
			cubemap = new RenderTexture(size, size, 16);
			((Texture)cubemap).dimension = (TextureDimension)4;
			screen = projector;
			screen.mainTexture = (Texture)(object)cubemap;
			FOV = curFOV;
		}

		private void Update()
		{
			if ((Object)(object)screen == (Object)null)
			{
				return;
			}
			Graphics.CopyTexture((Texture)(object)front.targetTexture, 0, (Texture)(object)cubemap, 4);
			if (((Component)back).gameObject.activeSelf)
			{
				Graphics.CopyTexture((Texture)(object)back.targetTexture, 0, (Texture)(object)cubemap, 5);
			}
			Graphics.CopyTexture((Texture)(object)right.targetTexture, 0, (Texture)(object)cubemap, 0);
			Graphics.CopyTexture((Texture)(object)left.targetTexture, 0, (Texture)(object)cubemap, 1);
			Graphics.CopyTexture((Texture)(object)up.targetTexture, 0, (Texture)(object)cubemap, 3);
			Graphics.CopyTexture((Texture)(object)down.targetTexture, 0, (Texture)(object)cubemap, 2);
			if (!player.IsLocked())
			{
				curFOV = Mathf.Clamp(curFOV + ((GameEntity)player).curBuffs.GetBuff("addFOV"), 60f, 315f);
				FOV = Math.ExpDecay(FOV, curFOV, 5f, Time.deltaTime);
				curFOV = settings.playerFOV;
				sprintFOV = curFOV + 15f;
			}
			if (!player.IsMoveLocked() && !CommandConsole.IsConsoleVisible())
			{
				bool flag = (bool)sliding.GetValue(player);
				if (player.IsSprinting() && player.IsGrounded(false) && !flag && !settings.disableSprintFov)
				{
					curFOV = sprintFOV;
				}
			}
		}

		private void OnDestroy()
		{
			cubemap.Release();
		}

		private void SetupCams(Camera orig, int size)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			Camera[] subCameras = GetSubCameras();
			foreach (Camera obj in subCameras)
			{
				obj.targetTexture = new RenderTexture(size, size, 16);
				obj.depth = orig.depth;
				obj.clearFlags = orig.clearFlags;
				obj.cullingMask = orig.cullingMask;
				obj.depthTextureMode = (DepthTextureMode)1;
			}
		}

		internal Camera[] GetSubCameras()
		{
			return (Camera[])(object)new Camera[6] { front, back, left, right, up, down };
		}
	}
	public class HelpingHand : MonoBehaviour
	{
		private ENT_Player player;

		private void FixedUpdate()
		{
			if ((Object)(object)player != (Object)null)
			{
				Hand[] hands = player.hands;
				foreach (Hand val in hands)
				{
					if (val.IsHolding() || val.IsLocked())
					{
						((Component)val.handBase).gameObject.layer = 28;
					}
					else
					{
						((Component)val.handBase).gameObject.layer = 8;
					}
				}
			}
			else
			{
				player = ENT_Player.GetPlayer();
			}
		}
	}
	[BepInPlugin("wk.barackobusiness.wideangle", "Wide Angle Camera", "2.0.2")]
	public class WideAnglePlugin : BaseUnityPlugin
	{
		private enum Quality
		{
			VeryLow = 0x100,
			Low = 0x200,
			Normal = 0x400,
			Extreme = 0x800
		}

		private enum Projection
		{
			Stereographic,
			Equidistant,
			Equisolid,
			Panini
		}

		private ConfigEntry<Quality> quality;

		private ConfigEntry<Projection> projection;

		private ConfigEntry<bool> syncHands;

		private ConfigEntry<bool> renderBackface;

		private GameObject wideAngleCamera;

		private Shader wideAngleShader;

		private Harmony patcher;

		private void Awake()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			quality = ((BaseUnityPlugin)this).Config.Bind<Quality>("General", "Cubemap Resolution", Quality.Low, "The default side length of a face on the cubemap. This setting controls quality and performance.");
			projection = ((BaseUnityPlugin)this).Config.Bind<Projection>("Projection Configuration", "Projection Technique", Projection.Stereographic, "The technique used to project the environment onto your screen.\r\nStereographic projection draws a ray through each point on the sphere onto the projected plane. Just like standard rectilinear, only the projection point is at the north pole instead of the origin of the sphere.\r\nIt is conformal, as in locally angles of intersections are preserved; circles remain circular at any given position on screen. This is the recommended and likely most comfortable projection to play with.\r\nEquidistant projection maps points on the viewing sphere to the projected plane such that distance from the center corresponds directly to angle measure between that point and the center on the globe.\r\nEquisolid projection maps the viewing sphere to a disk such that area on the disk accurately represents area at all regions of the sphere.\r\nPanini projects from a cylinder onto your view. The straightness of vertical lines is retained from rectilinear projection while allowing for a much wider field of view.");
			syncHands = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Synchronize Hands", true, "Whether to synchronize hands or not. When synchronized, a second wide angle projection camera is created with the sole purpose to render hands in the world, which incurs a not insignificant rendering cost.\r\nHowever hand sprites will be rendered appropriately in the position where you have grabbed and should not diverge from there.");
			renderBackface = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable backface", false, "Whether to render behind the player or not. Incurs additional performance cost but resolves black borders on the edges of the screen at high fields of view. Perhaps necessary for normal fovs on ultrawide screens.");
			if (LoadAssetBundle())
			{
				SceneManager.sceneLoaded += OnSceneLoaded;
				patcher = new Harmony("wk.barackobusiness.wideangle");
				patcher.PatchAll(typeof(UT_CameraTakeoverPatches));
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Wide angle views are NOW possible");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00e7: 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_01dc: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			if (((Scene)(ref scene)).name == "Intro")
			{
				return;
			}
			if (((Scene)(ref scene)).name == "Main-Menu")
			{
				GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Settings/Settings Menu/SettingsParent/Settings Pane/Video Settings/Options Tab/Video/SliderAsset - FOV/Slider").GetComponent<SubmitSlider>().maxValue = 270f;
				return;
			}
			((Component)GameObject.Find("Pause").transform.GetChild(0).GetChild(3).GetChild(0)
				.GetChild(0)
				.GetChild(4)
				.GetChild(1)
				.GetChild(0)
				.GetChild(7)
				.GetChild(1)).GetComponent<SubmitSlider>().maxValue = 270f;
			Transform transform = ((Component)Camera.main).transform;
			GameObject val = SetupProjector();
			((Renderer)val.GetComponent<MeshRenderer>()).material = new Material(wideAngleShader);
			((Renderer)val.GetComponent<MeshRenderer>()).material.renderQueue = 2000;
			val.transform.localPosition = new Vector3(0f, 0f, 0.5f);
			val.transform.SetParent(transform, false);
			val.layer = 31;
			GameObject obj = Object.Instantiate<GameObject>(wideAngleCamera, transform, false);
			((Object)obj).name = "Wide Angle Camera";
			CameraManager cameraManager = obj.AddComponent<CameraManager>();
			cameraManager.Init(((Renderer)val.GetComponent<MeshRenderer>()).material, Camera.main, renderBackface.Value, (int)quality.Value);
			CameraManager.Instance = cameraManager;
			Camera.main.nearClipPlane = 0f;
			Camera.main.farClipPlane = 1f;
			Camera.main.cullingMask = int.MinValue;
			Camera.main.orthographic = true;
			Camera.main.orthographicSize = 0.75f;
			Camera.main.useOcclusionCulling = false;
			Camera.main.clearFlags = (CameraClearFlags)2;
			if (syncHands.Value)
			{
				GameObject val2 = SetupProjector();
				((Renderer)val2.GetComponent<MeshRenderer>()).material = new Material(wideAngleShader);
				val2.transform.localPosition = new Vector3(0f, 0f, 0.25f);
				val2.transform.SetParent(transform, false);
				val2.layer = 31;
				Camera component = ((Component)transform.Find("Inventory Camera")).GetComponent<Camera>();
				GameObject val3 = Object.Instantiate<GameObject>(wideAngleCamera, transform, false);
				((Object)val3).name = "Wide Angle Hand Camera";
				CameraManager cameraManager2 = val3.AddComponent<CameraManager>();
				cameraManager2.Init(((Renderer)val2.GetComponent<MeshRenderer>()).material, component, renderBackface.Value, (int)quality.Value);
				CameraManager.HandInstance = cameraManager2;
				Camera[] subCameras = cameraManager2.GetSubCameras();
				foreach (Camera obj2 in subCameras)
				{
					obj2.clearFlags = (CameraClearFlags)2;
					obj2.cullingMask = 268435456;
				}
				val3.AddComponent<HelpingHand>();
			}
		}

		private GameObject SetupProjector()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_005f: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			Mesh val = new Mesh();
			((Object)val).name = "Triangle";
			val.vertices = (Vector3[])(object)new Vector3[3]
			{
				new Vector3(-1f, -1f, 0f),
				new Vector3(3f, -1f, 0f),
				new Vector3(-1f, 3f, 0f)
			};
			val.uv = (Vector2[])(object)new Vector2[3]
			{
				new Vector2(0f, 0f),
				new Vector2(2f, 0f),
				new Vector2(0f, 2f)
			};
			val.triangles = new int[3] { 2, 1, 0 };
			val.RecalculateBounds();
			GameObject val2 = new GameObject("Projector Screen");
			MeshFilter val3 = val2.AddComponent<MeshFilter>();
			MeshRenderer obj = val2.AddComponent<MeshRenderer>();
			((Renderer)obj).receiveShadows = false;
			((Renderer)obj).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).motionVectorGenerationMode = (MotionVectorGenerationMode)2;
			((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0;
			val3.sharedMesh = val;
			return val2;
		}

		private bool LoadAssetBundle()
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\WideAngleAssets");
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Wide angle views are NOT possible, please ensure the asset bundle is present in the same folder as the plugin");
				return false;
			}
			wideAngleCamera = val.LoadAsset<GameObject>("Wide Angle Camera");
			Shader[] array = val.LoadAllAssets<Shader>();
			foreach (Shader val2 in array)
			{
				if (((Object)val2).name == "Custom/" + projection.Value)
				{
					wideAngleShader = val2;
				}
			}
			if ((Object)(object)wideAngleCamera == (Object)null || (Object)(object)wideAngleShader == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Wide angle views are NOT possible, please reacquire the asset bundle from https://github.com/BarackOBusiness/WKWideAngleCamera");
			}
			Object.DontDestroyOnLoad((Object)(object)wideAngleCamera);
			Object.DontDestroyOnLoad((Object)(object)wideAngleShader);
			return true;
		}
	}
	public static class Math
	{
		public static float ExpDecay(float a, float b, float decay, float dt)
		{
			return b + (a - b) * Mathf.Exp((0f - decay) * dt);
		}
	}
	public static class UT_CameraTakeoverPatches
	{
		[HarmonyPatch(typeof(UT_CameraTakeover), "Start")]
		[HarmonyPostfix]
		public static void Postfix_Start(UT_CameraTakeover __instance)
		{
			__instance.fov = 229.18312f * Mathf.Atan(Mathf.Tan(MathF.PI / 8f) * Camera.main.aspect);
		}

		[HarmonyPatch(typeof(UT_CameraTakeover), "Update")]
		[HarmonyPostfix]
		public static void Postfix_Update(UT_CameraTakeover __instance, ref bool ___active)
		{
			CameraManager instance = CameraManager.Instance;
			if (___active)
			{
				float num = Math.ExpDecay(instance.FOV, __instance.fov, __instance.speed, Time.deltaTime);
				Debug.Log((object)$"Trying to set FOV, current {instance.FOV}, target {num}");
				instance.FOV = num;
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "wk.barackobusiness.wideangle";

		public const string PLUGIN_NAME = "Wide Angle Camera";

		public const string PLUGIN_VERSION = "2.0.2";
	}
}