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<Behaviour>(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<bool>(typeof(AttackPlayer), "isMining", attack))
{
return false;
}
if (Reflect.Get<bool>(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<bool> Enabled;
internal static ConfigEntry<KeyboardShortcut> ToggleKey;
internal static ConfigEntry<float> ShoulderOffset;
internal static ConfigEntry<float> ShoulderHeight;
internal static ConfigEntry<float> Distance;
internal static ConfigEntry<float> DistanceMin;
internal static ConfigEntry<float> DistanceMax;
internal static ConfigEntry<float> ZoomStep;
internal static ConfigEntry<float> Pitch;
internal static ConfigEntry<float> PitchMin;
internal static ConfigEntry<float> PitchMax;
internal static ConfigEntry<float> Fov;
internal static ConfigEntry<float> SensitivityX;
internal static ConfigEntry<float> SensitivityY;
internal static ConfigEntry<bool> InvertY;
internal static ConfigEntry<bool> RequireRightMouse;
internal static ConfigEntry<bool> FacingFollowsInput;
internal static ConfigEntry<float> FacingTurnSpeed;
internal static ConfigEntry<bool> FacingFreezeWhileOrbiting;
internal static ConfigEntry<bool> DofEnabled;
internal static ConfigEntry<float> DofIntensity;
internal static ConfigEntry<bool> DofAutoFocus;
internal static ConfigEntry<float> DofFocalLength;
internal static ConfigEntry<float> DofFocalSize;
internal static ConfigEntry<float> DofMaxAperture;
internal static ConfigEntry<bool> TargetingEnabled;
internal static ConfigEntry<KeyboardShortcut> TargetNextKey;
internal static ConfigEntry<KeyboardShortcut> TargetClearKey;
internal static ConfigEntry<float> TargetMaxRange;
internal static ConfigEntry<bool> 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<bool>("General", "Enabled", true, "Master switch. Turning this off hands the camera straight back to the game.");
ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)286, Array.Empty<KeyCode>()), "Switches between third person and the vanilla camera in-game.");
ShoulderOffset = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Rig", "ShoulderHeight", 1.6f, "Height of the look-at pivot above the player's feet, roughly head height.");
Distance = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "Distance", 4.5f, "Current camera distance. Updated as you zoom.");
DistanceMin = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "DistanceMin", 1.2f, "Closest zoom. Around 1.2 is close over-the-shoulder.");
DistanceMax = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "DistanceMax", 18f, "Furthest zoom. Large values approach the vanilla pulled-back feel.");
ZoomStep = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "ZoomStep", 1.1f, "Distance change per mouse-wheel notch.");
Pitch = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "Pitch", 18f, "Starting downward pitch in degrees.");
PitchMin = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "PitchMin", -25f, "Highest the camera can look up.");
PitchMax = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "PitchMax", 70f, "Lowest the camera can look down. Steep values approach a top-down view.");
Fov = ((BaseUnityPlugin)this).Config.Bind<float>("Rig", "FieldOfView", 55f, "Vertical field of view for the third-person camera.");
SensitivityX = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "SensitivityX", 3.2f, "Horizontal look speed.");
SensitivityY = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "SensitivityY", 2.2f, "Vertical look speed.");
InvertY = ((BaseUnityPlugin)this).Config.Bind<bool>("Look", "InvertY", false, "Invert vertical look.");
RequireRightMouse = ((BaseUnityPlugin)this).Config.Bind<bool>("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<bool>("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<float>("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<bool>("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<bool>("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<float>("DepthOfField", "Intensity", 0.35f, "0 to 1. Scales the aperture, which is what controls how strongly the\nbackground blurs.");
DofAutoFocus = ((BaseUnityPlugin)this).Config.Bind<bool>("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<float>("DepthOfField", "FocalLength", 4.5f, "Manual focus distance, used only when AutoFocusPlayer is off.");
DofFocalSize = ((BaseUnityPlugin)this).Config.Bind<float>("DepthOfField", "FocalSize", 0.05f, "Size of the in-focus band. Larger keeps more of the scene sharp.");
DofMaxAperture = ((BaseUnityPlugin)this).Config.Bind<float>("DepthOfField", "MaxAperture", 2.5f, "Aperture at Intensity 1.0. Raise for a more extreme blur ceiling.");
TargetingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("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<KeyboardShortcut>("Targeting", "NextTargetKey", new KeyboardShortcut((KeyCode)9, Array.Empty<KeyCode>()), "Cycle to the next valid target.");
TargetClearKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Targeting", "ClearTargetKey", new KeyboardShortcut((KeyCode)27, Array.Empty<KeyCode>()), "Drop the current target.");
TargetMaxRange = ((BaseUnityPlugin)this).Config.Bind<float>("Targeting", "MaxRange", 25f, "Maximum distance for a target to be selectable.");
TargetRequireOnScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("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<KeyValuePair<string, ConfigEntry<bool>>> Features()
{
yield return new KeyValuePair<string, ConfigEntry<bool>>("Third person camera", Enabled);
yield return new KeyValuePair<string, ConfigEntry<bool>>("Invert vertical look", InvertY);
yield return new KeyValuePair<string, ConfigEntry<bool>>("Hold RMB to rotate", RequireRightMouse);
yield return new KeyValuePair<string, ConfigEntry<bool>>("Facing follows movement", FacingFollowsInput);
yield return new KeyValuePair<string, ConfigEntry<bool>>("Freeze facing while orbiting", FacingFreezeWhileOrbiting);
yield return new KeyValuePair<string, ConfigEntry<bool>>("Depth of field", DofEnabled);
yield return new KeyValuePair<string, ConfigEntry<bool>>("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<string, FieldInfo> Cache = new Dictionary<string, FieldInfo>();
private static readonly HashSet<string> Reported = new HashSet<string>();
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<T>(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<MonsterDamage> Candidates = new List<MonsterDamage>();
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<MonsterDamage>();
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<CameraFollow>();
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<CinemachineVirtualCamera>();
((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;
}
}
}
}