using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Cinemachine; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("ReLegendThirdPerson")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.1.0")] [assembly: AssemblyInformationalVersion("0.2.1")] [assembly: AssemblyProduct("ReLegendThirdPerson")] [assembly: AssemblyTitle("ReLegendThirdPerson")] [assembly: AssemblyVersion("0.2.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 ReLegendThirdPerson { [HarmonyPatch] internal static class CameraPatches { [HarmonyPatch(typeof(MinimapCamera), "Update")] [HarmonyPostfix] private static void MinimapCamera_Update_Postfix() { if (ThirdPersonRig.Active && Plugin.Enabled.Value) { MinimapCamera.yRot = 0f; } } } internal static class DepthOfFieldControl { private static float _lastApplied = float.NaN; private static bool _lastEnabled; private static bool _warned; internal static void Tick() { try { CameraManager instance = CameraManager.instance; if ((Object)(object)instance == (Object)null) { return; } bool value = Plugin.DofEnabled.Value; Behaviour val = Reflect.Get(typeof(CameraManager), "depthOfField", instance); if ((Object)(object)val == (Object)null) { if (!_warned) { _warned = true; Plugin.Log.LogWarning((object)"No depth-of-field effect on CameraManager; DOF control is inert."); } return; } if (val.enabled != value) { val.enabled = value; _lastEnabled = value; _lastApplied = float.NaN; } if (value) { float num = Mathf.Clamp01(Plugin.DofIntensity.Value); float num2 = (Plugin.DofAutoFocus.Value ? Mathf.Max(0.1f, Plugin.Distance.Value) : Plugin.DofFocalLength.Value); float value2 = Plugin.DofFocalSize.Value; float num3 = num * Mathf.Max(0f, Plugin.DofMaxAperture.Value); float num4 = num2 * 1000f + value2 * 100f + num3; if (float.IsNaN(_lastApplied) || !Mathf.Approximately(num4, _lastApplied)) { _lastApplied = num4; instance.SetDoF(num2, value2, num3); } } } catch (Exception ex) { Plugin.Log.LogError((object)("Depth-of-field update failed: " + ex)); } } internal static void Reset() { _lastApplied = float.NaN; _lastEnabled = false; } } [HarmonyPatch] internal static class FacingPatches { [HarmonyPatch(typeof(MovementPlayer), "MovementDirection")] [HarmonyPostfix] private static void MovementDirection_Postfix(MovementPlayer __instance) { if (!Plugin.Enabled.Value || !Plugin.FacingFollowsInput.Value || !ThirdPersonRig.Active || (Plugin.FacingFreezeWhileOrbiting.Value && Plugin.RequireRightMouse.Value && Input.GetMouseButton(1))) { return; } try { Apply(__instance); } catch (Exception ex) { Plugin.Log.LogError((object)("Facing update failed: " + ex)); } } private static void Apply(MovementPlayer move) { //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_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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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) Vector3 moveDirection = move._moveDirection; moveDirection.y = 0f; if (!(((Vector3)(ref moveDirection)).sqrMagnitude < 0.0001f)) { PlayerHandler val = (((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.player : null); if (!((Object)(object)val == (Object)null) && ShouldTurn(val)) { Transform transform = ((Component)val).transform; Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref moveDirection)).normalized); float num = Mathf.Max(1f, Plugin.FacingTurnSpeed.Value) * Time.deltaTime; transform.rotation = Quaternion.RotateTowards(transform.rotation, val2, num); } } } private static bool ShouldTurn(PlayerHandler hero) { try { AttackPlayer attack = hero.Attack; if ((Object)(object)attack != (Object)null) { if (attack.isAttacking) { return false; } if (Reflect.Get(typeof(AttackPlayer), "isMining", attack)) { return false; } if (Reflect.Get(typeof(AttackPlayer), "isRolling", attack)) { return false; } } FarmActionPlayer farmAction = hero.farmAction; if ((Object)(object)farmAction != (Object)null && (farmAction.IsWatering || farmAction.IsHoe)) { return false; } MovementPlayer movement = hero.Movement; if ((Object)(object)movement != (Object)null && movement.isSwim) { return false; } TamingPlayer taming = hero.Taming; if ((Object)(object)taming != (Object)null && taming.isMounted) { return false; } } catch { return false; } return true; } } [BepInPlugin("com.community.relegend.thirdperson", "Re:Legend Third Person", "0.2.1")] public class Plugin : BaseUnityPlugin { public const string GUID = "com.community.relegend.thirdperson"; public const string NAME = "Re:Legend Third Person"; public const string VERSION = "0.2.1"; internal static ManualLogSource Log; internal static Plugin Instance; private Harmony _harmony; internal static ConfigEntry Enabled; internal static ConfigEntry ToggleKey; internal static ConfigEntry ShoulderOffset; internal static ConfigEntry ShoulderHeight; internal static ConfigEntry Distance; internal static ConfigEntry DistanceMin; internal static ConfigEntry DistanceMax; internal static ConfigEntry ZoomStep; internal static ConfigEntry Pitch; internal static ConfigEntry PitchMin; internal static ConfigEntry PitchMax; internal static ConfigEntry Fov; internal static ConfigEntry SensitivityX; internal static ConfigEntry SensitivityY; internal static ConfigEntry InvertY; internal static ConfigEntry RequireRightMouse; internal static ConfigEntry FacingFollowsInput; internal static ConfigEntry FacingTurnSpeed; internal static ConfigEntry FacingFreezeWhileOrbiting; internal static ConfigEntry DofEnabled; internal static ConfigEntry DofIntensity; internal static ConfigEntry DofAutoFocus; internal static ConfigEntry DofFocalLength; internal static ConfigEntry DofFocalSize; internal static ConfigEntry DofMaxAperture; internal static ConfigEntry TargetingEnabled; internal static ConfigEntry TargetNextKey; internal static ConfigEntry TargetClearKey; internal static ConfigEntry TargetMaxRange; internal static ConfigEntry TargetRequireOnScreen; private void Awake() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Master switch. Turning this off hands the camera straight back to the game."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", new KeyboardShortcut((KeyCode)286, Array.Empty()), "Switches between third person and the vanilla camera in-game."); ShoulderOffset = ((BaseUnityPlugin)this).Config.Bind("Rig", "ShoulderOffset", 0.6f, "Sideways offset from the player. Positive is over the right shoulder,\nnegative the left, 0 is centred behind."); ShoulderHeight = ((BaseUnityPlugin)this).Config.Bind("Rig", "ShoulderHeight", 1.6f, "Height of the look-at pivot above the player's feet, roughly head height."); Distance = ((BaseUnityPlugin)this).Config.Bind("Rig", "Distance", 4.5f, "Current camera distance. Updated as you zoom."); DistanceMin = ((BaseUnityPlugin)this).Config.Bind("Rig", "DistanceMin", 1.2f, "Closest zoom. Around 1.2 is close over-the-shoulder."); DistanceMax = ((BaseUnityPlugin)this).Config.Bind("Rig", "DistanceMax", 18f, "Furthest zoom. Large values approach the vanilla pulled-back feel."); ZoomStep = ((BaseUnityPlugin)this).Config.Bind("Rig", "ZoomStep", 1.1f, "Distance change per mouse-wheel notch."); Pitch = ((BaseUnityPlugin)this).Config.Bind("Rig", "Pitch", 18f, "Starting downward pitch in degrees."); PitchMin = ((BaseUnityPlugin)this).Config.Bind("Rig", "PitchMin", -25f, "Highest the camera can look up."); PitchMax = ((BaseUnityPlugin)this).Config.Bind("Rig", "PitchMax", 70f, "Lowest the camera can look down. Steep values approach a top-down view."); Fov = ((BaseUnityPlugin)this).Config.Bind("Rig", "FieldOfView", 55f, "Vertical field of view for the third-person camera."); SensitivityX = ((BaseUnityPlugin)this).Config.Bind("Look", "SensitivityX", 3.2f, "Horizontal look speed."); SensitivityY = ((BaseUnityPlugin)this).Config.Bind("Look", "SensitivityY", 2.2f, "Vertical look speed."); InvertY = ((BaseUnityPlugin)this).Config.Bind("Look", "InvertY", false, "Invert vertical look."); RequireRightMouse = ((BaseUnityPlugin)this).Config.Bind("Look", "HoldRightMouseToRotate", true, "Rotate only while right mouse is held. Turning this off gives free look,\nwhich conflicts with cursor-driven aiming and menu clicks."); FacingFollowsInput = ((BaseUnityPlugin)this).Config.Bind("Facing", "FollowMovementInput", true, "Turn the character to face the movement keys, independently of the camera.\nCamera orbit on its own never changes facing; only pressing a direction does."); FacingTurnSpeed = ((BaseUnityPlugin)this).Config.Bind("Facing", "TurnSpeed", 720f, "Degrees per second. Vanilla lerps at rotateRate 3, which visibly lags behind\nthe keys once the camera can swing freely. Lower this for a heavier feel."); FacingFreezeWhileOrbiting = ((BaseUnityPlugin)this).Config.Bind("Facing", "FreezeWhileOrbiting", true, "While right mouse is held the camera orbits and the character keeps its\nfacing. Movement input is camera-relative, so without this holding a\ndirection key while orbiting drags the body around with the camera."); DofEnabled = ((BaseUnityPlugin)this).Config.Bind("DepthOfField", "Enabled", false, "Take over the game's depth-of-field effect. Off leaves the scene's own\nsettings completely untouched."); DofIntensity = ((BaseUnityPlugin)this).Config.Bind("DepthOfField", "Intensity", 0.35f, "0 to 1. Scales the aperture, which is what controls how strongly the\nbackground blurs."); DofAutoFocus = ((BaseUnityPlugin)this).Config.Bind("DepthOfField", "AutoFocusPlayer", true, "Track focal length to the current camera distance so the character stays\nsharp as you zoom. Turn off to set the focal length by hand."); DofFocalLength = ((BaseUnityPlugin)this).Config.Bind("DepthOfField", "FocalLength", 4.5f, "Manual focus distance, used only when AutoFocusPlayer is off."); DofFocalSize = ((BaseUnityPlugin)this).Config.Bind("DepthOfField", "FocalSize", 0.05f, "Size of the in-focus band. Larger keeps more of the scene sharp."); DofMaxAperture = ((BaseUnityPlugin)this).Config.Bind("DepthOfField", "MaxAperture", 2.5f, "Aperture at Intensity 1.0. Raise for a more extreme blur ceiling."); TargetingEnabled = ((BaseUnityPlugin)this).Config.Bind("Targeting", "Enabled", false, "Tab targeting. Currently selection and tracking only: it picks a target and\nthe camera can orbit around it, but it does not yet redirect attacks.\nSee the README for why that part is not done blind."); TargetNextKey = ((BaseUnityPlugin)this).Config.Bind("Targeting", "NextTargetKey", new KeyboardShortcut((KeyCode)9, Array.Empty()), "Cycle to the next valid target."); TargetClearKey = ((BaseUnityPlugin)this).Config.Bind("Targeting", "ClearTargetKey", new KeyboardShortcut((KeyCode)27, Array.Empty()), "Drop the current target."); TargetMaxRange = ((BaseUnityPlugin)this).Config.Bind("Targeting", "MaxRange", 25f, "Maximum distance for a target to be selectable."); TargetRequireOnScreen = ((BaseUnityPlugin)this).Config.Bind("Targeting", "RequireOnScreen", true, "Only cycle through targets currently visible on screen."); _harmony = new Harmony("com.community.relegend.thirdperson"); try { _harmony.PatchAll(typeof(CameraPatches)); _harmony.PatchAll(typeof(FacingPatches)); Log.LogInfo((object)("Re:Legend Third Person 0.2.1 loaded. BepInEx " + typeof(BaseUnityPlugin).Assembly.GetName().Version?.ToString() + ", Harmony " + typeof(Harmony).Assembly.GetName().Version?.ToString() + ".")); } catch (Exception ex) { Log.LogError((object)("Patching failed, mod is inert: " + ex)); } } private void OnDestroy() { ThirdPersonRig.Teardown(); DepthOfFieldControl.Reset(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { //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_000d: 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) try { KeyboardShortcut value = ToggleKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0) { value = ToggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Enabled.Value = !Enabled.Value; SaveConfig(); Log.LogInfo((object)("Third person " + (Enabled.Value ? "enabled." : "disabled."))); } } ThirdPersonRig.Tick(); Targeting.Tick(); DepthOfFieldControl.Tick(); } catch (Exception ex) { Log.LogError((object)("Update failed: " + ex)); } } internal static IEnumerable>> Features() { yield return new KeyValuePair>("Third person camera", Enabled); yield return new KeyValuePair>("Invert vertical look", InvertY); yield return new KeyValuePair>("Hold RMB to rotate", RequireRightMouse); yield return new KeyValuePair>("Facing follows movement", FacingFollowsInput); yield return new KeyValuePair>("Freeze facing while orbiting", FacingFreezeWhileOrbiting); yield return new KeyValuePair>("Depth of field", DofEnabled); yield return new KeyValuePair>("Tab targeting", TargetingEnabled); } internal static void SaveConfig() { try { ((BaseUnityPlugin)Instance).Config.Save(); } catch (Exception ex) { Log.LogError((object)("Could not save config: " + ex)); } } } internal static class Reflect { private static readonly Dictionary Cache = new Dictionary(); private static readonly HashSet Reported = new HashSet(); private static FieldInfo Find(Type type, string name) { string text = type.FullName + "::" + name; if (Cache.TryGetValue(text, out var value)) { return value; } value = AccessTools.Field(type, name); Cache[text] = value; if (value == null && Reported.Add(text)) { Plugin.Log.LogError((object)("Field not found: " + text + ". The game may have been updated.")); } return value; } internal static T Get(Type type, string name, object instance) { FieldInfo fieldInfo = Find(type, name); if (fieldInfo == null) { return default(T); } try { object value = fieldInfo.GetValue(instance); return (value is T) ? ((T)value) : default(T); } catch (Exception ex) { Plugin.Log.LogError((object)("Reading " + type.Name + "." + name + " failed: " + ex.Message)); return default(T); } } internal static void Set(Type type, string name, object instance, object value) { FieldInfo fieldInfo = Find(type, name); if (fieldInfo == null) { return; } try { fieldInfo.SetValue(instance, value); } catch (Exception ex) { Plugin.Log.LogError((object)("Writing " + type.Name + "." + name + " failed: " + ex.Message)); } } internal static bool Invoke(Type type, string name, object instance) { MethodInfo methodInfo = AccessTools.Method(type, name, (Type[])null, (Type[])null); if (methodInfo == null) { Plugin.Log.LogError((object)("Method not found: " + type.FullName + "::" + name)); return false; } try { methodInfo.Invoke(instance, null); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("Invoking " + type.Name + "." + name + " failed: " + ex.Message)); return false; } } } internal static class Targeting { private static readonly List Candidates = new List(); private static MonsterDamage _current; private static float _nextRefresh; internal static MonsterDamage Current => _current; internal static Transform CurrentTransform { get { if (!Plugin.TargetingEnabled.Value) { return null; } if ((Object)(object)_current == (Object)null) { _current = null; return null; } return ((Component)_current).transform; } } internal static void Tick() { //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_0021: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.TargetingEnabled.Value) { _current = null; return; } try { KeyboardShortcut value = Plugin.TargetClearKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0) { value = Plugin.TargetClearKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { if ((Object)(object)_current != (Object)null) { Plugin.Log.LogInfo((object)"Target cleared."); } _current = null; return; } } value = Plugin.TargetNextKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0) { value = Plugin.TargetNextKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { CycleTarget(); } } if ((Object)(object)_current != (Object)null && !IsValid(_current)) { _current = null; } } catch (Exception ex) { Plugin.Log.LogError((object)("Targeting failed: " + ex)); _current = null; } } private static void CycleTarget() { Refresh(); if (Candidates.Count == 0) { _current = null; Plugin.Log.LogInfo((object)"No valid targets in range."); return; } int num = (((Object)(object)_current == (Object)null) ? (-1) : Candidates.IndexOf(_current)); num = (num + 1) % Candidates.Count; _current = Candidates[num]; Plugin.Log.LogInfo((object)("Target: " + ((Object)((Component)_current).gameObject).name + " (" + (num + 1) + "/" + Candidates.Count + ")")); } private static void Refresh() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextRefresh && Candidates.Count > 0) { return; } _nextRefresh = Time.unscaledTime + 0.5f; Candidates.Clear(); PlayerHandler val = (((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.player : null); if ((Object)(object)val == (Object)null) { return; } MonsterDamage[] array = Object.FindObjectsOfType(); if (array == null) { return; } Vector3 origin = ((Component)val).transform.position; foreach (MonsterDamage val2 in array) { if (IsValid(val2)) { Candidates.Add(val2); } } Candidates.Sort(delegate(MonsterDamage a, MonsterDamage b) { //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) //IL_0016: 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_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_0035: Unknown result type (might be due to invalid IL or missing references) Vector3 val3 = ((Component)a).transform.position - origin; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; val3 = ((Component)b).transform.position - origin; float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude; return sqrMagnitude.CompareTo(sqrMagnitude2); }); } private static bool IsValid(MonsterDamage m) { //IL_0050: 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_0091: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m == (Object)null) { return false; } if (m.deadMotionStart) { return false; } if (!((Component)m).gameObject.activeInHierarchy) { return false; } PlayerHandler val = (((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.player : null); if ((Object)(object)val == (Object)null) { return false; } Vector3 val2 = ((Component)m).transform.position - ((Component)val).transform.position; float value = Plugin.TargetMaxRange.Value; if (((Vector3)(ref val2)).sqrMagnitude > value * value) { return false; } if (Plugin.TargetRequireOnScreen.Value && !IsOnScreen(((Component)m).transform.position)) { return false; } return true; } private static bool IsOnScreen(Vector3 worldPos) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0026: 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_0040: 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) Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return true; } Vector3 val = main.WorldToViewportPoint(worldPos); if (val.z > 0f && val.x >= 0f && val.x <= 1f && val.y >= 0f) { return val.y <= 1f; } return false; } } internal static class ThirdPersonRig { private const int ActivePriority = 5000; private const int IdlePriority = -100; private static GameObject _rigRoot; private static GameObject _vcamObject; private static CinemachineVirtualCamera _vcam; private static Transform _lookTarget; private static float _yaw; private static float _pitch; private static bool _initialised; private static bool _wasActive; internal static bool Active { get; private set; } internal static float Yaw => _yaw; internal static void Tick() { if (!Plugin.Enabled.Value || VanillaShouldOwnCamera()) { if (_wasActive) { SetActive(active: false); } _wasActive = false; Active = false; } else if (EnsureRig()) { if (!_wasActive) { SetActive(active: true); _wasActive = true; SeedFromPlayerFacing(); } Active = true; ReadLookInput(); ReadZoomInput(); ApplyTransform(); } } internal static void Teardown() { try { if ((Object)(object)_vcamObject != (Object)null) { Object.Destroy((Object)(object)_vcamObject); } if ((Object)(object)_rigRoot != (Object)null) { Object.Destroy((Object)(object)_rigRoot); } } catch { } _vcamObject = null; _rigRoot = null; _vcam = null; _lookTarget = null; _initialised = false; Active = false; } private static bool VanillaShouldOwnCamera() { try { GameManager instance = GameManager.instance; PlayerHandler val = (((Object)(object)instance != (Object)null) ? instance.player : null); if ((Object)(object)val == (Object)null) { return true; } if ((Object)(object)val.Taming != (Object)null && (val.Taming.tamingStarted || val.Taming.isMounted)) { return true; } if ((Object)(object)val.Fishing != (Object)null && val.Fishing.GetFish()) { return true; } if ((Object)(object)CustomCameraControl.instance == (Object)null) { return true; } CameraFollow val2 = Object.FindObjectOfType(); if ((Object)(object)val2 != (Object)null && (val2.cameraTaming || val2.isShopping || val2.fishResult)) { return true; } } catch { return true; } return false; } private static bool EnsureRig() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00b7: Expected O, but got Unknown if (_initialised && (Object)(object)_vcam != (Object)null && (Object)(object)_rigRoot != (Object)null) { return true; } try { GameManager instance = GameManager.instance; if ((Object)(object)(((Object)(object)instance != (Object)null) ? instance.player : null) == (Object)null) { return false; } if ((Object)(object)_rigRoot == (Object)null) { _rigRoot = new GameObject("ReLegendThirdPerson_Pivot"); Object.DontDestroyOnLoad((Object)(object)_rigRoot); GameObject val = new GameObject("LookTarget"); val.transform.SetParent(_rigRoot.transform, false); _lookTarget = val.transform; } if ((Object)(object)_vcamObject == (Object)null) { _vcamObject = new GameObject("ReLegendThirdPerson_VCam"); Object.DontDestroyOnLoad((Object)(object)_vcamObject); _vcam = _vcamObject.AddComponent(); ((CinemachineVirtualCameraBase)_vcam).Priority = -100; _vcam.m_Lens.FieldOfView = Plugin.Fov.Value; ((CinemachineVirtualCameraBase)_vcam).Follow = null; ((CinemachineVirtualCameraBase)_vcam).LookAt = null; } _initialised = true; Plugin.Log.LogInfo((object)"Third-person rig created."); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("Could not create the third-person rig: " + ex)); return false; } } private static void SetActive(bool active) { if (!((Object)(object)_vcam == (Object)null)) { ((CinemachineVirtualCameraBase)_vcam).Priority = (active ? 5000 : (-100)); Plugin.Log.LogInfo((object)("Third-person camera " + (active ? "engaged" : "released") + ".")); } } private static void SeedFromPlayerFacing() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) try { PlayerHandler player = GameManager.instance.player; if (!((Object)(object)player == (Object)null)) { _yaw = ((Component)player).transform.eulerAngles.y; _pitch = Plugin.Pitch.Value; } } catch { } } private static void ReadLookInput() { if (!Plugin.RequireRightMouse.Value || Input.GetMouseButton(1)) { float num = Input.GetAxisRaw("Mouse X") * Plugin.SensitivityX.Value; float num2 = Input.GetAxisRaw("Mouse Y") * Plugin.SensitivityY.Value; if (Plugin.InvertY.Value) { num2 = 0f - num2; } _yaw += num; _pitch = Mathf.Clamp(_pitch - num2, Plugin.PitchMin.Value, Plugin.PitchMax.Value); if (_yaw > 360f) { _yaw -= 360f; } else if (_yaw < 0f) { _yaw += 360f; } } } private static void ReadZoomInput() { float axisRaw = Input.GetAxisRaw("Mouse ScrollWheel"); if (!Mathf.Approximately(axisRaw, 0f)) { float num = Plugin.Distance.Value - axisRaw * Plugin.ZoomStep.Value * 10f; Plugin.Distance.Value = Mathf.Clamp(num, Plugin.DistanceMin.Value, Plugin.DistanceMax.Value); } } private static void ApplyTransform() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00b7: 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_00c7: 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_00ca: 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_00da: 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_00e1: 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_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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_0057: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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) PlayerHandler player = GameManager.instance.player; if ((Object)(object)player == (Object)null || (Object)(object)_vcamObject == (Object)null) { return; } Vector3 val = ((Component)player).transform.position + Vector3.up * Plugin.ShoulderHeight.Value; Transform currentTransform = Targeting.CurrentTransform; if ((Object)(object)currentTransform != (Object)null) { Vector3 val2 = currentTransform.position - val; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.01f) { Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized); _yaw = ((Quaternion)(ref val3)).eulerAngles.y; } } Quaternion val4 = Quaternion.Euler(_pitch, _yaw, 0f); Vector3 val5 = val4 * Vector3.right; Vector3 val6 = val4 * Vector3.back; Vector3 val7 = val + val5 * Plugin.ShoulderOffset.Value; Vector3 val8 = val7 + val6 * Plugin.Distance.Value; _lookTarget.position = val7; _vcamObject.transform.position = val8; _vcamObject.transform.rotation = Quaternion.LookRotation(val7 - val8); if ((Object)(object)_vcam != (Object)null && !Mathf.Approximately(_vcam.m_Lens.FieldOfView, Plugin.Fov.Value)) { _vcam.m_Lens.FieldOfView = Plugin.Fov.Value; } } } }