Decompiled source of TruckMirror v0.1.0

TruckMirror.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Dobutsu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A wide full-length mirror in the R.E.P.O. truck")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+c4bcb05ee7d0e6dce2625d3de4937dd33184dd87")]
[assembly: AssemblyProduct("TruckMirror")]
[assembly: AssemblyTitle("TruckMirror")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 TruckMirror
{
	internal static class LocalAvatarReveal
	{
		private static readonly List<Renderer> Found = new List<Renderer>();

		private static readonly List<Renderer> Shown = new List<Renderer>();

		private static int localLayer = -1;

		public static void Show()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			PlayerAvatar instance = PlayerAvatar.instance;
			if (!Object.op_Implicit((Object)(object)instance) || instance.isDisabled || !Object.op_Implicit((Object)(object)instance.playerAvatarVisuals))
			{
				return;
			}
			if (localLayer < 0)
			{
				localLayer = LayerMask.NameToLayer("PlayerVisualsLocal");
			}
			((Component)instance.playerAvatarVisuals).GetComponentsInChildren<Renderer>(false, Found);
			foreach (Renderer item in Found)
			{
				if (((Component)item).gameObject.layer == localLayer && (int)item.shadowCastingMode == 3)
				{
					item.shadowCastingMode = (ShadowCastingMode)1;
					Shown.Add(item);
				}
			}
			Found.Clear();
		}

		public static void Hide()
		{
			foreach (Renderer item in Shown)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					item.shadowCastingMode = (ShadowCastingMode)3;
				}
			}
			Shown.Clear();
		}
	}
	internal sealed class MirrorConfig
	{
		public readonly ConfigEntry<bool> Enabled;

		public readonly ConfigEntry<float> Width;

		public readonly ConfigEntry<float> Height;

		public readonly ConfigEntry<float> HeightAboveFloor;

		public readonly ConfigEntry<float> SideOffset;

		public readonly ConfigEntry<bool> Frame;

		public readonly ConfigEntry<Color> Tint;

		public readonly ConfigEntry<bool> Lamp;

		public readonly ConfigEntry<float> LampIntensity;

		public readonly ConfigEntry<float> KeepDistance;

		public readonly ConfigEntry<float> ResolutionScale;

		public readonly ConfigEntry<bool> ReflectionShadows;

		public readonly ConfigEntry<int> UpdateEveryNFrames;

		public readonly ConfigEntry<float> MaxDistance;

		public event Action? LayoutChanged;

		public MirrorConfig(ConfigFile config)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_014f: 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_01b3: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Expected O, but got Unknown
			MirrorConfig mirrorConfig = this;
			Enabled = config.Bind<bool>("Mirror", "Enabled", true, "Show the mirror in the truck");
			Width = config.Bind<float>("Mirror", "Width", 2.25f, new ConfigDescription("Mirror width in meters. The wall is free for about 2.4 m between the charging station on the left and the pipe on the right; a wider mirror is partly hidden behind them", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3.25f), Array.Empty<object>()));
			Height = config.Bind<float>("Mirror", "Height", 2.2f, new ConfigDescription("Mirror height in meters (a robot is about 1.7 m tall)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3.5f), Array.Empty<object>()));
			HeightAboveFloor = config.Bind<float>("Mirror", "HeightAboveFloor", 0.25f, new ConfigDescription("Gap between the floor and the bottom of the mirror, meters", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1.5f), Array.Empty<object>()));
			SideOffset = config.Bind<float>("Mirror", "SideOffset", 0.15f, new ConfigDescription("Shift to the right (as seen when facing the mirror), meters; the default centers it on the free wall", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1.5f, 1.5f), Array.Empty<object>()));
			Frame = config.Bind<bool>("Mirror", "Frame", true, "Dark frame around the mirror");
			Tint = config.Bind<Color>("Mirror", "Tint", new Color(0.93f, 0.96f, 0.96f, 1f), "Color the reflection is multiplied by (a real mirror is slightly darker and greener)");
			Lamp = config.Bind<bool>("Mirror", "Lamp", true, "Lamp above the mirror, lighting whoever stands in front of it");
			LampIntensity = config.Bind<float>("Mirror", "LampIntensity", 2.5f, new ConfigDescription("Brightness of the lamp", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>()));
			KeepDistance = config.Bind<float>("Mirror", "KeepDistance", 0.35f, new ConfigDescription("Invisible barrier in front of the mirror, meters: without it you can walk up close enough for your robot's head to poke through the mirror. 0 turns it off. Only blocks you, not items", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ResolutionScale = config.Bind<float>("Performance", "ResolutionScale", 1f, new ConfigDescription("Reflection pixels per game pixel: 1 matches the game's own pixelated resolution", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 2f), Array.Empty<object>()));
			ReflectionShadows = config.Bind<bool>("Performance", "ReflectionShadows", true, "Render shadows in the reflection (the truck lights cast shadows again for the mirror camera)");
			UpdateEveryNFrames = config.Bind<int>("Performance", "UpdateEveryNFrames", 1, new ConfigDescription("Redraw the reflection every N frames", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			MaxDistance = config.Bind<float>("Performance", "MaxDistance", 15f, new ConfigDescription("Don't redraw the reflection farther than this from the mirror, meters (the game's fog ends at 15 m)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), Array.Empty<object>()));
			ConfigEntryBase[] layout = (ConfigEntryBase[])(object)new ConfigEntryBase[10]
			{
				(ConfigEntryBase)Enabled,
				(ConfigEntryBase)Width,
				(ConfigEntryBase)Height,
				(ConfigEntryBase)HeightAboveFloor,
				(ConfigEntryBase)SideOffset,
				(ConfigEntryBase)Frame,
				(ConfigEntryBase)Tint,
				(ConfigEntryBase)Lamp,
				(ConfigEntryBase)LampIntensity,
				(ConfigEntryBase)KeepDistance
			};
			config.SettingChanged += delegate(object _, SettingChangedEventArgs args)
			{
				if (Array.IndexOf(layout, args.ChangedSetting) >= 0)
				{
					mirrorConfig.LayoutChanged?.Invoke();
				}
			};
		}
	}
	internal sealed class ConfigWatcher : MonoBehaviour
	{
		private const float Interval = 1f;

		private ConfigFile config;

		private DateTime lastWrite;

		private float nextCheck;

		public static void Start(ConfigFile config)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			GameObject val = new GameObject("TruckMirror Config Watcher")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			ConfigWatcher configWatcher = val.AddComponent<ConfigWatcher>();
			configWatcher.config = config;
			configWatcher.lastWrite = LastWrite(config);
		}

		private void Update()
		{
			if (!(Time.unscaledTime < nextCheck))
			{
				nextCheck = Time.unscaledTime + 1f;
				DateTime dateTime = LastWrite(config);
				if (!(dateTime == lastWrite))
				{
					lastWrite = dateTime;
					config.Reload();
					Plugin.Log.LogInfo((object)"Config reloaded");
				}
			}
		}

		private static DateTime LastWrite(ConfigFile config)
		{
			if (!File.Exists(config.ConfigFilePath))
			{
				return default(DateTime);
			}
			return File.GetLastWriteTimeUtc(config.ConfigFilePath);
		}
	}
	internal static class MirrorSpawner
	{
		private static Transform? truck;

		public static void OnTruckReady(Transform healer)
		{
			truck = TruckLocator.FindRoot(healer);
			if (!Object.op_Implicit((Object)(object)truck))
			{
				Plugin.Log.LogWarning((object)("No truck around " + ((Object)healer).name + ", no mirror"));
			}
			else
			{
				Respawn();
			}
		}

		public static void Respawn()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)MirrorSurface.Instance))
			{
				Object.Destroy((Object)(object)((Component)MirrorSurface.Instance).gameObject);
			}
			if (Object.op_Implicit((Object)(object)truck) && Plugin.Settings.Enabled.Value)
			{
				MirrorSurface mirrorSurface = MirrorSurface.Create(truck);
				if (Object.op_Implicit((Object)(object)mirrorSurface))
				{
					Plugin.Log.LogInfo((object)$"Mirror placed in {((Object)truck).name} at {((Component)mirrorSurface).transform.position}");
				}
			}
		}
	}
	internal sealed class MirrorSurface : MonoBehaviour
	{
		private const int HiddenLayers = 352;

		private const float WallGap = 0.05f;

		private const float WallZ = 0.026f;

		private const float FrameWidth = 0.06f;

		private const float FrameDepth = 0.05f;

		private const float LampDepth = 0.14f;

		private const float BlockerHeight = 2f;

		private const float MinEyeDistance = 0.05f;

		private const int SizeStep = 32;

		private const int MaxTextureSize = 4096;

		private static bool rendering;

		private readonly Vector3[] screenCorners = (Vector3[])(object)new Vector3[4];

		private float width;

		private float height;

		private MeshRenderer surface;

		private Mesh mesh;

		private Material material;

		private Material? frameMaterial;

		private Material? glowMaterial;

		private Camera reflectionCamera;

		private RenderTexture? texture;

		private int lastRenderFrame = -1;

		public static MirrorSurface? Instance { get; private set; }

		public static MirrorSurface? Create(Transform truck)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("UI/Default");
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogError((object)"Shader UI/Default not found, no mirror");
				return null;
			}
			MirrorConfig settings = Plugin.Settings;
			GameObject val2 = new GameObject("Truck Mirror");
			val2.transform.SetParent(truck, false);
			val2.transform.localPosition = new Vector3(TruckLocator.FrontWallFaceX(truck) + 0.05f, 0.7f + settings.HeightAboveFloor.Value + settings.Height.Value / 2f, settings.SideOffset.Value);
			val2.transform.localRotation = Quaternion.LookRotation(Vector3.left, Vector3.up);
			MirrorSurface mirrorSurface = val2.AddComponent<MirrorSurface>();
			mirrorSurface.Build(val, settings.Width.Value, settings.Height.Value, 0f - (settings.HeightAboveFloor.Value + settings.Height.Value / 2f));
			return mirrorSurface;
		}

		private void Awake()
		{
			Instance = this;
		}

		private void Build(Shader shader, float w, float h, float floorY)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			width = w;
			height = h;
			mesh = BuildQuad(w, h);
			((Component)this).gameObject.AddComponent<MeshFilter>().sharedMesh = mesh;
			material = UnlitMaterial(shader, "Truck Mirror", Plugin.Settings.Tint.Value);
			material.mainTexture = (Texture)(object)Texture2D.blackTexture;
			surface = ((Component)this).gameObject.AddComponent<MeshRenderer>();
			((Renderer)surface).sharedMaterial = material;
			((Renderer)surface).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)surface).receiveShadows = false;
			((Renderer)surface).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)surface).reflectionProbeUsage = (ReflectionProbeUsage)0;
			((Renderer)surface).motionVectorGenerationMode = (MotionVectorGenerationMode)2;
			GameObject val = new GameObject("Truck Mirror Camera");
			val.transform.SetParent(((Component)this).transform, false);
			reflectionCamera = val.AddComponent<Camera>();
			((Behaviour)reflectionCamera).enabled = false;
			if (Plugin.Settings.Frame.Value)
			{
				BuildFrame(w, h);
			}
			if (Plugin.Settings.Lamp.Value)
			{
				BuildLamp(shader, w, h);
			}
			if (Plugin.Settings.KeepDistance.Value > 0f)
			{
				BuildBlocker(w, floorY, Plugin.Settings.KeepDistance.Value);
			}
		}

		private static Material UnlitMaterial(Shader shader, string name, Color color)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			Material val = new Material(shader)
			{
				name = name,
				color = color,
				renderQueue = 2450
			};
			val.SetFloat("unity_GUIZTestMode", 4f);
			val.SetVector("_TextureSampleAdd", Vector4.zero);
			return val;
		}

		private static Mesh BuildQuad(float w, float h)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_002e: 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_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_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_005a: 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_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_0092: 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_00a8: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e2: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			float num = w / 2f;
			float num2 = h / 2f;
			Mesh val = new Mesh();
			((Object)val).name = "Truck Mirror";
			val.vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(0f - num, 0f - num2),
				new Vector3(num, 0f - num2),
				new Vector3(num, num2),
				new Vector3(0f - num, num2)
			};
			val.uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(1f, 0f),
				new Vector2(0f, 0f),
				new Vector2(0f, 1f),
				new Vector2(1f, 1f)
			};
			val.colors = (Color[])(object)new Color[4]
			{
				Color.white,
				Color.white,
				Color.white,
				Color.white
			};
			val.normals = (Vector3[])(object)new Vector3[4]
			{
				Vector3.back,
				Vector3.back,
				Vector3.back,
				Vector3.back
			};
			val.triangles = new int[6] { 0, 3, 2, 0, 2, 1 };
			val.RecalculateBounds();
			return val;
		}

		private void BuildFrame(float w, float h)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			Material boxMaterial = DarkMetal();
			AddBox("Frame", new Vector3(0f, (h + 0.06f) / 2f), new Vector3(w + 0.12f, 0.06f, 0.05f), boxMaterial);
			AddBox("Frame", new Vector3(0f, (0f - (h + 0.06f)) / 2f), new Vector3(w + 0.12f, 0.06f, 0.05f), boxMaterial);
			AddBox("Frame", new Vector3((0f - (w + 0.06f)) / 2f, 0f), new Vector3(0.06f, h, 0.05f), boxMaterial);
			AddBox("Frame", new Vector3((w + 0.06f) / 2f, 0f), new Vector3(0.06f, h, 0.05f), boxMaterial);
		}

		private void BuildLamp(Shader unlit, float w, float h)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			float num = w * 0.6f;
			float num2 = h / 2f + 0.06f + 0.04f;
			float num3 = -0.044f;
			AddBox("Lamp", new Vector3(0f, num2 + 0.03f, num3), new Vector3(num, 0.06f, 0.14f), DarkMetal());
			glowMaterial = UnlitMaterial(unlit, "Truck Mirror Lamp", new Color(1f, 0.94f, 0.82f));
			glowMaterial.mainTexture = (Texture)(object)Texture2D.whiteTexture;
			AddBox("Lamp Glow", new Vector3(0f, num2 - 0.008f, num3), new Vector3(num - 0.04f, 0.016f, 0.1f), glowMaterial);
			GameObject val = new GameObject("Truck Mirror Lamp Light");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = new Vector3(0f, num2 - 0.05f, -0.114f);
			val.transform.localRotation = Quaternion.LookRotation(new Vector3(0f, -1f, -1f), Vector3.up);
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)0;
			obj.spotAngle = 120f;
			obj.range = 4.5f;
			obj.intensity = Plugin.Settings.LampIntensity.Value;
			obj.color = new Color(1f, 0.92f, 0.8f);
			obj.shadows = (LightShadows)0;
		}

		private void BuildBlocker(float w, float floorY, float depth)
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			GameObject val = new GameObject("Truck Mirror Blocker")
			{
				layer = LayerMask.NameToLayer("PlayerOnlyCollision")
			};
			val.transform.SetParent(((Component)this).transform, false);
			BoxCollider obj = val.AddComponent<BoxCollider>();
			obj.center = new Vector3(0f, floorY + 1f, (0f - depth) / 2f);
			obj.size = new Vector3(w + 0.6f, 2f, depth);
		}

		private Material DarkMetal()
		{
			//IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)frameMaterial))
			{
				return frameMaterial;
			}
			Shader val = Shader.Find("Standard");
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = Shader.Find("Legacy Shaders/Diffuse");
			}
			frameMaterial = new Material(val)
			{
				name = "Truck Mirror Frame",
				color = new Color(0.1f, 0.1f, 0.11f)
			};
			frameMaterial.SetFloat("_Glossiness", 0.4f);
			frameMaterial.SetFloat("_Metallic", 0.6f);
			return frameMaterial;
		}

		private void AddBox(string name, Vector3 position, Vector3 size, Material boxMaterial)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			((Object)obj).name = "Truck Mirror " + name;
			obj.transform.SetParent(((Component)this).transform, false);
			obj.transform.localPosition = position;
			obj.transform.localScale = size;
			((Renderer)obj.GetComponent<MeshRenderer>()).sharedMaterial = boxMaterial;
		}

		private void OnWillRenderObject()
		{
			if (!rendering)
			{
				Camera current = Camera.current;
				if (Object.op_Implicit((Object)(object)current) && !((Object)(object)current != (Object)(object)Camera.main) && (lastRenderFrame < 0 || Time.frameCount - lastRenderFrame >= Plugin.Settings.UpdateEveryNFrames.Value))
				{
					RenderReflection(current);
				}
			}
		}

		private void RenderReflection(Camera eye)
		{
			//IL_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_01e8: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00dc: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			MirrorConfig settings = Plugin.Settings;
			Transform transform = ((Component)this).transform;
			Vector3 val = -transform.forward;
			Vector3 up = transform.up;
			Vector3 position = transform.position;
			Vector3 position2 = ((Component)eye).transform.position;
			float num = Vector3.Dot(position2 - position, val);
			if (num < 0.05f || num > settings.MaxDistance.Value)
			{
				return;
			}
			EnsureTexture(TextureSize(eye));
			Camera val2 = reflectionCamera;
			val2.CopyFrom(eye);
			((Behaviour)val2).enabled = false;
			val2.targetTexture = texture;
			val2.cullingMask = eye.cullingMask & -353;
			val2.useOcclusionCulling = false;
			val2.depthTextureMode = (DepthTextureMode)0;
			val2.allowMSAA = false;
			val2.ResetWorldToCameraMatrix();
			((Component)val2).transform.SetPositionAndRotation(position2 - 2f * num * val, Quaternion.LookRotation(val, up));
			Vector3 val3 = position - ((Component)val2).transform.position;
			float num2 = Vector3.Dot(val3, ((Component)val2).transform.right);
			float num3 = Vector3.Dot(val3, up);
			float num4 = num;
			float num5 = Mathf.Max(eye.farClipPlane, num4 + 0.1f);
			val2.nearClipPlane = num4;
			val2.farClipPlane = num5;
			val2.projectionMatrix = Matrix4x4.Frustum(num2 - width / 2f, num2 + width / 2f, num3 - height / 2f, num3 + height / 2f, num4, num5);
			ShadowQuality shadows = QualitySettings.shadows;
			if (!settings.ReflectionShadows.Value)
			{
				QualitySettings.shadows = (ShadowQuality)0;
			}
			rendering = true;
			((Renderer)surface).forceRenderingOff = true;
			LocalAvatarReveal.Show();
			try
			{
				val2.Render();
				lastRenderFrame = Time.frameCount;
			}
			finally
			{
				LocalAvatarReveal.Hide();
				((Renderer)surface).forceRenderingOff = false;
				rendering = false;
				QualitySettings.shadows = shadows;
			}
		}

		private Vector2Int TextureSize(Camera eye)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_006a: 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)
			//IL_007a: 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_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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_009d: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: 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_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.Settings.ResolutionScale.Value;
			float num = Mathf.Min((float)Mathf.Max(eye.pixelWidth, eye.pixelHeight) * 2f * value, 4096f);
			Transform transform = ((Component)this).transform;
			Vector3 val = transform.right * (width / 2f);
			Vector3 val2 = transform.up * (height / 2f);
			Vector3 position = transform.position;
			screenCorners[0] = eye.WorldToScreenPoint(position - val - val2);
			screenCorners[1] = eye.WorldToScreenPoint(position + val - val2);
			screenCorners[2] = eye.WorldToScreenPoint(position + val + val2);
			screenCorners[3] = eye.WorldToScreenPoint(position - val + val2);
			float pixels;
			float pixels2;
			if (screenCorners[0].z <= 0f || screenCorners[1].z <= 0f || screenCorners[2].z <= 0f || screenCorners[3].z <= 0f)
			{
				pixels = num * Mathf.Min(1f, width / height);
				pixels2 = num * Mathf.Min(1f, height / width);
			}
			else
			{
				pixels = Mathf.Max(Flat(screenCorners[1] - screenCorners[0]), Flat(screenCorners[2] - screenCorners[3])) * value;
				pixels2 = Mathf.Max(Flat(screenCorners[3] - screenCorners[0]), Flat(screenCorners[2] - screenCorners[1])) * value;
			}
			return new Vector2Int(Snap(pixels, num), Snap(pixels2, num));
		}

		private static float Flat(Vector3 v)
		{
			//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_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)
			Vector2 val = new Vector2(v.x, v.y);
			return ((Vector2)(ref val)).magnitude;
		}

		private static int Snap(float pixels, float max)
		{
			return Mathf.Max(32, Mathf.CeilToInt(Mathf.Min(pixels, max) / 32f) * 32);
		}

		private void EnsureTexture(Vector2Int size)
		{
			//IL_005c: 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)
			if (!Object.op_Implicit((Object)(object)texture) || ((Texture)texture).width != ((Vector2Int)(ref size)).x || ((Texture)texture).height != ((Vector2Int)(ref size)).y)
			{
				if (Object.op_Implicit((Object)(object)texture))
				{
					RenderTexture.ReleaseTemporary(texture);
				}
				RenderTextureFormat val = (RenderTextureFormat)(SystemInfo.SupportsRenderTextureFormat((RenderTextureFormat)22) ? 22 : 0);
				texture = RenderTexture.GetTemporary(((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, 24, val);
				((Texture)texture).filterMode = (FilterMode)0;
				((Texture)texture).wrapMode = (TextureWrapMode)1;
				material.mainTexture = (Texture)(object)texture;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			if (Object.op_Implicit((Object)(object)texture))
			{
				RenderTexture.ReleaseTemporary(texture);
			}
			Object.Destroy((Object)(object)material);
			if (Object.op_Implicit((Object)(object)frameMaterial))
			{
				Object.Destroy((Object)(object)frameMaterial);
			}
			if (Object.op_Implicit((Object)(object)glowMaterial))
			{
				Object.Destroy((Object)(object)glowMaterial);
			}
			Object.Destroy((Object)(object)mesh);
		}
	}
	[HarmonyPatch]
	internal static class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(TruckHealer), "Start")]
		private static void TruckReady(TruckHealer __instance)
		{
			MirrorSpawner.OnTruckReady(((Component)__instance).transform);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerAvatarVisuals), "Update")]
		private static void LocalHeadFollowsLook(PlayerAvatarVisuals __instance)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)MirrorSurface.Instance) && !__instance.isMenuAvatar && !__instance.expressionAvatar && !(__instance.showSelfOverrideTimer > 0f))
			{
				PlayerAvatar playerAvatar = __instance.playerAvatar;
				if (Object.op_Implicit((Object)(object)playerAvatar) && !((Object)(object)playerAvatar != (Object)(object)PlayerAvatar.instance) && !playerAvatar.isDisabled && Object.op_Implicit((Object)(object)LevelGenerator.Instance) && LevelGenerator.Instance.Generated && __instance.lookSideSpring.setup)
				{
					float lastPosition = __instance.lookUpSpring.lastPosition;
					__instance.headUpTransform.localRotation = Quaternion.Euler(lastPosition * 0.5f, 0f, 0f);
					__instance.bodyTopUpTransform.localRotation = Quaternion.Euler(lastPosition * 0.25f, 0f, 0f);
					Quaternion lastRotation = __instance.lookSideSpring.lastRotation;
					__instance.headSideTransform.localRotation = lastRotation;
					__instance.bodyTopSideTransform.localRotation = Quaternion.Slerp(Quaternion.identity, lastRotation, 0.5f);
				}
			}
		}
	}
	[BepInPlugin("dobutsu.repo.truckmirror", "TruckMirror", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "dobutsu.repo.truckmirror";

		public const string Name = "TruckMirror";

		public const string Version = "0.1.0";

		internal static ManualLogSource Log;

		internal static MirrorConfig Settings;

		private void Awake()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new MirrorConfig(((BaseUnityPlugin)this).Config);
			Settings.LayoutChanged += MirrorSpawner.Respawn;
			ConfigWatcher.Start(((BaseUnityPlugin)this).Config);
			new Harmony("dobutsu.repo.truckmirror").PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"TruckMirror 0.1.0 loaded");
		}
	}
	internal static class TruckLocator
	{
		public const float FloorY = 0.7f;

		private const float FrontWallX = -24.13f;

		private const string BodyPath = "Mesh/Truck Body";

		private const string FrontWallPath = "Mesh/Truck Body/Colliders/Front Wall";

		public static Transform? FindRoot(Transform from)
		{
			Transform val = from;
			while (Object.op_Implicit((Object)(object)val))
			{
				if (Object.op_Implicit((Object)(object)val.Find("Mesh/Truck Body")))
				{
					return val;
				}
				val = val.parent;
			}
			return null;
		}

		public static float FrontWallFaceX(Transform root)
		{
			//IL_0076: 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_0086: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Transform val = root.Find("Mesh/Truck Body/Colliders/Front Wall");
			BoxCollider val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<BoxCollider>() : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				Plugin.Log.LogWarning((object)(((Object)root).name + ": no Mesh/Truck Body/Colliders/Front Wall collider, using the default wall position"));
				return -24.13f;
			}
			float num = float.MinValue;
			Vector3 val3 = default(Vector3);
			for (int i = 0; i < 8; i++)
			{
				((Vector3)(ref val3))..ctor((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1)));
				Vector3 val4 = val2.center + Vector3.Scale(val2.size / 2f, val3);
				num = Mathf.Max(num, root.InverseTransformPoint(((Component)val2).transform.TransformPoint(val4)).x);
			}
			if (Mathf.Abs(num - -24.13f) > 0.5f)
			{
				Plugin.Log.LogWarning((object)$"{((Object)root).name}: front wall at x={num:F2}, expected {-24.13f}; using the default");
				return -24.13f;
			}
			return num;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}