using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Cleverous.Prodigy;
using Cleverous.Prodigy.Input;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Tableflip;
using UnityEngine;
using UnityEngine.InputSystem;
[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("PartGhost")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 PartGhost")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1")]
[assembly: AssemblyProduct("PartGhost.FateCameraTurn")]
[assembly: AssemblyTitle("PartGhost.FateCameraTurn")]
[assembly: AssemblyVersion("0.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace PartGhost.FateControls
{
internal static class ControlsCommon
{
internal sealed class LegacyGate
{
private readonly MethodBase target;
private readonly string patch;
private float nextCheck = float.NegativeInfinity;
internal bool Owns { get; private set; } = true;
internal LegacyGate(Type gameType, string method, string patch)
{
target = AccessTools.Method(gameType, method, (Type[])null, (Type[])null);
this.patch = patch;
}
internal void Refresh()
{
if (!(Time.unscaledTime < nextCheck))
{
nextCheck = Time.unscaledTime + 1f;
Patches val = ((target == null) ? null : Harmony.GetPatchInfo(target));
Owns = val == null || !val.Prefixes.Concat(val.Postfixes).Any((Patch p) => p.owner == "local.fatecoop.prototype" && p.PatchMethod.Name == patch);
}
}
}
private static Type rebindApi;
private static Func<bool> rebindBlocked;
private static FieldInfo legacyActive;
private static FieldInfo legacyDowned;
private static bool dependenciesDirty;
internal static Type Api => rebindApi;
internal static bool Blocked
{
get
{
if (!InputBlocker.AnyBlockingUiMenuIsOpen && !InventoryUI.IsDraggingItem && !LegacyDowned)
{
return rebindBlocked?.Invoke() ?? false;
}
return true;
}
}
private static bool LegacyDowned
{
get
{
if (legacyActive == null || legacyDowned == null)
{
return false;
}
object value = legacyActive.GetValue(null);
if (value != null)
{
return (bool)legacyDowned.GetValue(value);
}
return false;
}
}
static ControlsCommon()
{
dependenciesDirty = true;
AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoaded;
}
private static void AssemblyLoaded(object sender, AssemblyLoadEventArgs e)
{
dependenciesDirty = true;
}
internal static void Prepare()
{
if (dependenciesDirty)
{
dependenciesDirty = false;
Type type = null;
rebindApi = null;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
rebindApi = rebindApi ?? assembly.GetType("ZombieGhost.Rebind.RebindApi", throwOnError: false);
type = type ?? assembly.GetType("FateCoop.Prototype.Plugin", throwOnError: false);
}
MethodInfo methodInfo = rebindApi?.GetProperty("IsInputBlocked")?.GetGetMethod();
rebindBlocked = ((methodInfo == null) ? null : ((Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), methodInfo)));
legacyActive = ((type == null) ? null : AccessTools.Field(type, "Active"));
legacyDowned = ((type == null) ? null : AccessTools.Field(type, "downed"));
}
}
internal static object Register(string guid, string name, params (string id, InputAction action, string label, string category)[] actions)
{
Type api = Api;
if (api == null)
{
return null;
}
object obj = api.GetMethod("RegisterProvider").Invoke(null, new object[2] { guid, name });
try
{
for (int i = 0; i < actions.Length; i++)
{
(string, InputAction, string, string) tuple = actions[i];
obj.GetType().GetMethod("RegisterAction").Invoke(obj, new object[5] { tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, null });
}
return obj;
}
catch
{
(obj as IDisposable)?.Dispose();
throw;
}
}
internal static void Hook(Harmony harmony, Type source, string targetType, string method, string prefix = null, string postfix = null)
{
//IL_0025: 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)
MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName(targetType), method, (Type[])null, (Type[])null) ?? throw new MissingMethodException(targetType, method);
harmony.Patch((MethodBase)methodInfo, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(source, prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(source, postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
internal static InputAction Button(string name, string path)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
InputAction val = new InputAction(name, (InputActionType)1, path, (string)null, (string)null, "Button");
val.Enable();
return val;
}
}
[BepInPlugin("partghost.fate.cameraturn", "FATE Camera Turn", "0.1.1")]
public sealed class CameraTurnPlugin : BaseUnityPlugin
{
public const string Guid = "partghost.fate.cameraturn";
private static CameraTurnPlugin active;
private Harmony harmony;
private InputAction drag;
private object provider;
private ConfigEntry<float> speed;
private float yaw;
private Vector2 start;
private bool dragging;
private bool legacyWarned;
private ProdigyCamera cameraOwner;
private ControlsCommon.LegacyGate legacy;
private static readonly FieldRef<ProdigyCamera, Quaternion> OriginalRotation = AccessTools.FieldRefAccess<ProdigyCamera, Quaternion>("originalRotation");
private static readonly FieldRef<ProdigyCamera, float> OriginalYaw = AccessTools.FieldRefAccess<ProdigyCamera, float>("originalYRotation");
private static readonly FieldRef<MiniMapIconUI, Quaternion> SavedRotation = AccessTools.FieldRefAccess<MiniMapIconUI, Quaternion>("savedRotation");
private void Awake()
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Expected O, but got Unknown
if (!((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "Enabled", true, "Enable mouse-drag camera turning.").Value)
{
return;
}
active = this;
speed = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "CameraTurnSpeed", 0.25f, new ConfigDescription("Degrees per pixel while the camera turn button is held.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), Array.Empty<object>()));
drag = ControlsCommon.Button("camera.drag", "<Mouse>/middleButton");
harmony = new Harmony("partghost.fate.cameraturn");
legacy = new ControlsCommon.LegacyGate(typeof(ProdigyCamera), "UpdateCameraRotation", "BeforeCameraRotation");
try
{
ControlsCommon.Hook(harmony, typeof(CameraTurnPlugin), typeof(ProdigyCamera).FullName, "UpdateCameraRotation", "Rotate");
ControlsCommon.Hook(harmony, typeof(CameraTurnPlugin), typeof(MiniMapIconUI).FullName, "LateUpdate", null, "Minimap");
((BaseUnityPlugin)this).Logger.LogInfo((object)"FATE Camera Turn 0.1.1 ready; standalone controls.");
}
catch (Exception ex)
{
harmony.UnpatchSelf();
active = null;
drag.Dispose();
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
}
private bool Owns()
{
if (legacy.Owns)
{
return true;
}
if (!legacyWarned)
{
legacyWarned = true;
((BaseUnityPlugin)this).Logger.LogWarning((object)"Original co-op camera controls installed. Standalone camera suspended; set its Controls.KeyboardMovement=false and restart.");
}
return false;
}
private static bool Rotate(ProdigyCamera __instance)
{
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: 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_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: 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_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
CameraTurnPlugin cameraTurnPlugin = active;
if (cameraTurnPlugin == null)
{
return true;
}
ControlsCommon.Prepare();
cameraTurnPlugin.legacy.Refresh();
if (!cameraTurnPlugin.Owns())
{
return true;
}
if (cameraTurnPlugin.provider == null && ControlsCommon.Api != null)
{
cameraTurnPlugin.provider = ControlsCommon.Register("partghost.fate.cameraturn", "Camera Turn", ("drag", cameraTurnPlugin.drag, "Hold to turn camera", "Camera"));
}
if ((Object)(object)cameraTurnPlugin.cameraOwner != (Object)(object)__instance)
{
cameraTurnPlugin.cameraOwner = __instance;
cameraTurnPlugin.yaw = 0f;
cameraTurnPlugin.dragging = false;
}
Mouse current = Mouse.current;
InputBroker instance = SingletonBehaviour<InputBroker>.Instance;
if (ControlsCommon.Blocked)
{
cameraTurnPlugin.dragging = false;
return false;
}
if (cameraTurnPlugin.drag.IsPressed())
{
if (!cameraTurnPlugin.dragging)
{
cameraTurnPlugin.start = ((current != null) ? ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue() : Vector2.zero);
cameraTurnPlugin.dragging = true;
}
if (current != null)
{
cameraTurnPlugin.yaw += ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue().x * cameraTurnPlugin.speed.Value;
}
}
else if (cameraTurnPlugin.dragging)
{
if (current != null)
{
current.WarpCursorPosition(cameraTurnPlugin.start);
}
cameraTurnPlugin.dragging = false;
}
if ((Object)(object)instance != (Object)null && !instance.HoldingSpellWheel)
{
cameraTurnPlugin.yaw -= instance.CameraRotateInputValue * 120f * Time.unscaledDeltaTime;
}
cameraTurnPlugin.yaw = Mathf.Repeat(cameraTurnPlugin.yaw + 180f, 360f) - 180f;
Vector3 eulerAngles = ((Quaternion)(ref OriginalRotation.Invoke(__instance))).eulerAngles;
((Component)__instance).transform.localRotation = Quaternion.Euler(eulerAngles.x, OriginalYaw.Invoke(__instance) + cameraTurnPlugin.yaw, eulerAngles.z);
return false;
}
private static void Minimap(MiniMapIconUI __instance)
{
//IL_002a: 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_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: 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_00a5: 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_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
CameraTurnPlugin cameraTurnPlugin = active;
if (cameraTurnPlugin != null && cameraTurnPlugin.Owns() && !((Object)(object)ProdigyCamera.GameCamera == (Object)null))
{
Quaternion val = SavedRotation.Invoke(__instance);
if (__instance.isCamera)
{
((Component)__instance).transform.rotation = Quaternion.AngleAxis(cameraTurnPlugin.yaw, Vector3.up) * val;
return;
}
Vector3 val2 = val * Vector3.up;
float num = Mathf.Atan2(val2.x, val2.z) * 57.29578f;
((Component)__instance).transform.rotation = Quaternion.AngleAxis(((Component)ProdigyCamera.GameCamera).transform.eulerAngles.y - num, Vector3.up) * val;
}
}
private void OnApplicationQuit()
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
(provider as IDisposable)?.Dispose();
InputAction obj2 = drag;
if (obj2 != null)
{
obj2.Dispose();
}
active = null;
}
}
}