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);
}
}