Decompiled source of ArrowCam v0.1.2

plugins/ArrowCam.dll

Decompiled 21 hours ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("YakkityFast")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("YakkityFast")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ea282da8-693d-4cf1-bf7a-8ecac0827eaa")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ArrowCamMod;

[BepInPlugin("com.oathorse.arrowcam", "ArrowCam", "0.1.2")]
public class ArrowCamPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.oathorse.arrowcam";

	public const string PluginName = "ArrowCam";

	public const string PluginVersion = "0.1.2";

	public static ConfigEntry<int> PipWidth;

	public static ConfigEntry<int> PipHeight;

	public static ConfigEntry<int> PipMarginRight;

	public static ConfigEntry<int> PipMarginTop;

	public static ConfigEntry<float> CameraFOV;

	public static ConfigEntry<float> LingerDuration;

	public static ConfigEntry<float> FadeDuration;

	private readonly Harmony _harmony = new Harmony("com.oathorse.arrowcam");

	public static ArrowCamPlugin Instance { get; private set; }

	private void Awake()
	{
		Instance = this;
		PipWidth = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PipWidth", 320, "Width of the kill-cam inset in pixels.");
		PipHeight = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PipHeight", 180, "Height of the kill-cam inset in pixels.");
		PipMarginRight = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PipMarginRight", 10, "Gap from the right edge of the screen.");
		PipMarginTop = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PipMarginTop", 240, "Gap from the top of the screen (positions it below minimap).");
		CameraFOV = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "FOV", 60f, "Field of view for the projectile camera.");
		LingerDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "LingerSeconds", 1.5f, "Seconds the PiP stays frozen at impact.");
		FadeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "FadeSeconds", 0.5f, "Seconds the PiP takes to fade out after the linger.");
		_harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ArrowCam loaded.");
	}

	private void OnDestroy()
	{
		_harmony.UnpatchSelf();
	}
}
public class ArrowCamSession : MonoBehaviour
{
	private enum Phase
	{
		Riding,
		Lingering,
		FadingOut,
		Dead
	}

	private Phase _phase;

	private float _timer;

	private bool _cleaned;

	private Transform _projectile;

	private Camera _cam;

	private RenderTexture _rt;

	private static readonly Vector3 LocalOffset = new Vector3(0f, 0.06f, -0.35f);

	private static readonly Vector3 LocalLookDelta = new Vector3(0f, -0.08f, 1f);

	private GameObject _uiRoot;

	private Image _border;

	private RawImage _rawImage;

	public void Init(Transform projectileTf)
	{
		_projectile = projectileTf;
		CreateRT();
		CreateCamera();
		CreateUI();
	}

	public void FreezeAndLinger()
	{
		if (_phase == Phase.Riding)
		{
			_projectile = null;
			_timer = 0f;
			_phase = Phase.Lingering;
		}
	}

	public bool IsTracking(Transform t)
	{
		if (_phase == Phase.Riding)
		{
			return (Object)(object)_projectile == (Object)(object)t;
		}
		return false;
	}

	private void LateUpdate()
	{
		switch (_phase)
		{
		case Phase.Riding:
			if ((Object)(object)_projectile == (Object)null)
			{
				FreezeAndLinger();
			}
			else
			{
				FollowProjectile();
			}
			break;
		case Phase.Lingering:
			_timer += Time.deltaTime;
			if (_timer >= ArrowCamPlugin.LingerDuration.Value)
			{
				if ((Object)(object)_cam != (Object)null)
				{
					((Behaviour)_cam).enabled = false;
				}
				_timer = 0f;
				_phase = Phase.FadingOut;
			}
			break;
		case Phase.FadingOut:
		{
			_timer += Time.deltaTime;
			float num = Mathf.Clamp01(_timer / Mathf.Max(0.001f, ArrowCamPlugin.FadeDuration.Value));
			ApplyAlpha(1f - num);
			if (num >= 1f)
			{
				Cleanup();
			}
			break;
		}
		case Phase.Dead:
			break;
		}
	}

	private void OnDestroy()
	{
		Cleanup();
	}

	private void FollowProjectile()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: 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_0048: 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_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)
		if (!((Object)(object)_cam == (Object)null))
		{
			((Component)_cam).transform.position = _projectile.TransformPoint(LocalOffset);
			Transform transform = ((Component)_cam).transform;
			Transform projectile = _projectile;
			Vector3 localLookDelta = LocalLookDelta;
			transform.rotation = Quaternion.LookRotation(projectile.TransformDirection(((Vector3)(ref localLookDelta)).normalized), _projectile.up);
		}
	}

	private void ApplyAlpha(float a)
	{
		//IL_0014: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: 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_005c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_border != (Object)null)
		{
			Color color = ((Graphic)_border).color;
			color.a = 0.75f * a;
			((Graphic)_border).color = color;
		}
		if ((Object)(object)_rawImage != (Object)null)
		{
			Color color2 = ((Graphic)_rawImage).color;
			color2.a = a;
			((Graphic)_rawImage).color = color2;
		}
	}

	private void Cleanup()
	{
		if (!_cleaned)
		{
			_cleaned = true;
			_phase = Phase.Dead;
			if ((Object)(object)_uiRoot != (Object)null)
			{
				_uiRoot.SetActive(false);
				Object.Destroy((Object)(object)_uiRoot);
				_uiRoot = null;
			}
			if ((Object)(object)_cam != (Object)null)
			{
				_cam.targetTexture = null;
				Object.Destroy((Object)(object)((Component)_cam).gameObject);
				_cam = null;
			}
			if ((Object)(object)_rt != (Object)null)
			{
				_rt.Release();
				Object.Destroy((Object)(object)_rt);
				_rt = null;
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}

	private void CreateRT()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		_rt = new RenderTexture(ArrowCamPlugin.PipWidth.Value, ArrowCamPlugin.PipHeight.Value, 16, (RenderTextureFormat)0)
		{
			name = "ArrowCam_RT"
		};
		_rt.Create();
	}

	private void CreateCamera()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		GameObject val = new GameObject("ArrowCam_Camera");
		Object.DontDestroyOnLoad((Object)(object)val);
		_cam = val.AddComponent<Camera>();
		_cam.fieldOfView = ArrowCamPlugin.CameraFOV.Value;
		_cam.nearClipPlane = 0.05f;
		_cam.farClipPlane = 500f;
		_cam.targetTexture = _rt;
		_cam.depth = -2f;
		_cam.cullingMask = -1;
		_cam.clearFlags = (CameraClearFlags)1;
		((Behaviour)_cam).enabled = true;
	}

	private void CreateUI()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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)
		//IL_0141: Expected O, but got Unknown
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: 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)
		_uiRoot = new GameObject("ArrowCam_UI");
		Object.DontDestroyOnLoad((Object)(object)_uiRoot);
		Canvas val = _uiRoot.AddComponent<Canvas>();
		val.renderMode = (RenderMode)0;
		val.sortingOrder = 100;
		CanvasScaler obj = _uiRoot.AddComponent<CanvasScaler>();
		obj.uiScaleMode = (ScaleMode)1;
		obj.referenceResolution = new Vector2(1920f, 1080f);
		_uiRoot.AddComponent<GraphicRaycaster>();
		GameObject val2 = new GameObject("ArrowCam_Panel");
		val2.transform.SetParent(((Component)val).transform, false);
		RectTransform obj2 = val2.AddComponent<RectTransform>();
		Vector2 val3 = default(Vector2);
		((Vector2)(ref val3))..ctor(1f, 1f);
		obj2.anchorMax = val3;
		obj2.anchorMin = val3;
		obj2.pivot = new Vector2(1f, 1f);
		obj2.sizeDelta = new Vector2((float)(ArrowCamPlugin.PipWidth.Value + 4), (float)(ArrowCamPlugin.PipHeight.Value + 4));
		obj2.anchoredPosition = new Vector2((float)(-ArrowCamPlugin.PipMarginRight.Value), (float)(-ArrowCamPlugin.PipMarginTop.Value));
		_border = val2.AddComponent<Image>();
		((Graphic)_border).color = new Color(0f, 0f, 0f, 0.75f);
		GameObject val4 = new GameObject("ArrowCam_Image");
		val4.transform.SetParent(val2.transform, false);
		RectTransform obj3 = val4.AddComponent<RectTransform>();
		obj3.anchorMin = Vector2.zero;
		obj3.anchorMax = Vector2.one;
		obj3.offsetMin = new Vector2(2f, 2f);
		obj3.offsetMax = new Vector2(-2f, -2f);
		_rawImage = val4.AddComponent<RawImage>();
		_rawImage.texture = (Texture)(object)_rt;
	}
}
[HarmonyPatch(typeof(Projectile), "Setup")]
internal static class Patch_Projectile_Setup
{
	private static void Postfix(Projectile __instance, Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemData item, ItemData ammo)
	{
		//IL_0026: 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_0031: Expected O, but got Unknown
		Player val = (Player)(object)((owner is Player) ? owner : null);
		if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && (item != null || ammo != null))
		{
			GameObject val2 = new GameObject("ArrowCam_Session");
			Object.DontDestroyOnLoad((Object)val2);
			val2.AddComponent<ArrowCamSession>().Init(((Component)__instance).transform);
		}
	}
}
[HarmonyPatch(typeof(Projectile), "OnHit")]
internal static class Patch_Projectile_OnHit
{
	private static void Prefix(Projectile __instance)
	{
		ArrowCamSession[] array = Object.FindObjectsOfType<ArrowCamSession>();
		foreach (ArrowCamSession arrowCamSession in array)
		{
			if (arrowCamSession.IsTracking(((Component)__instance).transform))
			{
				arrowCamSession.FreezeAndLinger();
				break;
			}
		}
	}
}
[HarmonyPatch(typeof(Chat), "InputText")]
internal static class Patch_Chat_InputText
{
	private static bool Prefix(Chat __instance)
	{
		string text = ((TMP_InputField)((Terminal)__instance).m_terminalInstance.m_input).text.Trim();
		if (!text.StartsWith("/arrowcam", StringComparison.OrdinalIgnoreCase))
		{
			return true;
		}
		string[] array = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
		string sub = ((array.Length > 1) ? array[1].ToLowerInvariant() : "");
		string arg = ((array.Length > 2) ? array[2] : "");
		string message = HandleCommand(sub, arg);
		PrintToChat(__instance, message);
		((TMP_InputField)((Terminal)__instance).m_terminalInstance.m_input).text = "";
		return false;
	}

	private static string HandleCommand(string sub, string arg)
	{
		CultureInfo invariantCulture = CultureInfo.InvariantCulture;
		NumberStyles style = NumberStyles.Float;
		switch (sub)
		{
		case "help":
		case "":
			return "ArrowCam settings:\n" + $"  width        = {ArrowCamPlugin.PipWidth.Value}\n" + $"  height       = {ArrowCamPlugin.PipHeight.Value}\n" + $"  marginright  = {ArrowCamPlugin.PipMarginRight.Value}\n" + $"  margintop    = {ArrowCamPlugin.PipMarginTop.Value}\n" + $"  fov          = {ArrowCamPlugin.CameraFOV.Value}\n" + $"  linger       = {ArrowCamPlugin.LingerDuration.Value}\n" + $"  fade         = {ArrowCamPlugin.FadeDuration.Value}\n" + "Usage: /arrowcam <setting> <value>";
		case "width":
		{
			if (!int.TryParse(arg, out var result2))
			{
				return "Usage: /arrowcam width <int>";
			}
			ArrowCamPlugin.PipWidth.Value = result2;
			return $"ArrowCam: width = {result2}";
		}
		case "height":
		{
			if (!int.TryParse(arg, out var result5))
			{
				return "Usage: /arrowcam height <int>";
			}
			ArrowCamPlugin.PipHeight.Value = result5;
			return $"ArrowCam: height = {result5}";
		}
		case "marginright":
		{
			if (!int.TryParse(arg, out var result7))
			{
				return "Usage: /arrowcam marginright <int>";
			}
			ArrowCamPlugin.PipMarginRight.Value = result7;
			return $"ArrowCam: marginright = {result7}";
		}
		case "margintop":
		{
			if (!int.TryParse(arg, out var result3))
			{
				return "Usage: /arrowcam margintop <int>";
			}
			ArrowCamPlugin.PipMarginTop.Value = result3;
			return $"ArrowCam: margintop = {result3}";
		}
		case "fov":
		{
			if (!float.TryParse(arg, style, invariantCulture, out var result6))
			{
				return "Usage: /arrowcam fov <float>";
			}
			ArrowCamPlugin.CameraFOV.Value = result6;
			return $"ArrowCam: fov = {result6}";
		}
		case "linger":
		{
			if (!float.TryParse(arg, style, invariantCulture, out var result4))
			{
				return "Usage: /arrowcam linger <float>";
			}
			ArrowCamPlugin.LingerDuration.Value = result4;
			return $"ArrowCam: linger = {result4}";
		}
		case "fade":
		{
			if (!float.TryParse(arg, style, invariantCulture, out var result))
			{
				return "Usage: /arrowcam fade <float>";
			}
			ArrowCamPlugin.FadeDuration.Value = result;
			return $"ArrowCam: fade = {result}";
		}
		default:
			return "ArrowCam: unknown setting '" + sub + "'. Type /arrowcam for help.";
		}
	}

	private static void PrintToChat(Chat chat, string message)
	{
		((Terminal)Chat.instance).AddString(message);
	}
}