Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ScrollToFirstPerson v1.1.0
ScrollToFirstPerson.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace ScrollToFirstPerson; [BepInPlugin("com.burks.scrolltofirstperson", "Scroll To First Person", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ScrollToFirstPersonPlugin : BaseUnityPlugin { public const string GUID = "com.burks.scrolltofirstperson"; public const string NAME = "Scroll To First Person"; public const string VERSION = "1.1.0"; public static ManualLogSource Log; public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> FaceLook; public static ConfigEntry<bool> FaceLookOnlyFirstPerson; public static bool VPlusReady; public static ConfigEntry<float> Cooldown; private void Awake() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Scroll in past the closest zoom to enter Valheim Plus first person; scroll out to leave it."); Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SwitchCooldownSeconds", 0.3f, "Minimum time between switches, so one long spin of the wheel does not flip back and forth."); FaceLook = ((BaseUnityPlugin)this).Config.Bind<bool>("FaceLookDirection", "Enabled", true, "Your character always turns to face the way the camera is looking, instead of the way you are walking."); FaceLookOnlyFirstPerson = ((BaseUnityPlugin)this).Config.Bind<bool>("FaceLookDirection", "OnlyInFirstPerson", false, "If true, only do this while Valheim Plus first person is active; third person behaves as normal."); if ((int)SystemInfo.graphicsDeviceType != 4) { Harmony val = new Harmony("com.burks.scrolltofirstperson"); VPlusReady = VPlus.Init(); if (VPlusReady) { val.CreateClassProcessor(typeof(CameraPatch)).Patch(); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Valheim Plus first-person code was not found in the form this mod expects; scroll switching is off."); } val.CreateClassProcessor(typeof(FacePatch)).Patch(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Scroll To First Person 1.1.0 loaded."); } } } public static class VPlus { private static FieldInfo _isFirstPerson; private static FieldInfo _saved3rd; private static FieldInfo _savedFps; private static FieldInfo _zoomSens; private static FieldInfo _minDist; private static FieldInfo _maxDist; private static MethodInfo _setupFP; private static PropertyInfo _current; private static PropertyInfo _firstPerson; private static PropertyInfo _isEnabled; private static float _enabledCheckedAt = -999f; private static bool _enabledCached; private static readonly FieldRef<Character, Transform> Head = AccessTools.FieldRefAccess<Character, Transform>("m_head"); public static bool IsFirstPerson => (bool)_isFirstPerson.GetValue(null); public static bool Init() { try { Type type = AccessTools.TypeByName("ValheimPlus.FirstPerson.VPlusFirstPerson"); if (type == null) { return false; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type nestedType = type.GetNestedType("DynamicPerson", bindingAttr); Type nestedType2 = type.GetNestedType("CameraConstants", bindingAttr); Type nestedType3 = type.GetNestedType("GameCamera_Update_Patch", bindingAttr); if (nestedType == null || nestedType2 == null || nestedType3 == null) { return false; } _isFirstPerson = nestedType.GetField("isFirstPerson", bindingAttr); _saved3rd = nestedType.GetField("noVPFP_3rdOffset", bindingAttr); _savedFps = nestedType.GetField("noVPFP_fpsOffset", bindingAttr); _zoomSens = nestedType2.GetField("zoomSens", bindingAttr); _minDist = nestedType2.GetField("minDistance", bindingAttr); _maxDist = nestedType2.GetField("maxDistance", bindingAttr); _setupFP = nestedType3.GetMethod("SetupFP", bindingAttr); Type type2 = AccessTools.TypeByName("ValheimPlus.Configurations.Configuration"); if (type2 != null) { _current = type2.GetProperty("Current", bindingAttr); _firstPerson = type2.GetProperty("FirstPerson", bindingAttr); if (_firstPerson != null) { _isEnabled = _firstPerson.PropertyType.GetProperty("IsEnabled", bindingAttr); } } return _isFirstPerson != null && _saved3rd != null && _savedFps != null && _zoomSens != null && _minDist != null && _maxDist != null && _setupFP != null && _current != null && _firstPerson != null && _isEnabled != null; } catch (Exception ex) { ScrollToFirstPersonPlugin.Log.LogWarning((object)("Could not hook into Valheim Plus: " + ex.Message)); return false; } } public static bool FeatureEnabled() { if (Time.unscaledTime - _enabledCheckedAt < 1f) { return _enabledCached; } _enabledCheckedAt = Time.unscaledTime; try { object value = _current.GetValue(null, null); object obj = ((value != null) ? _firstPerson.GetValue(value, null) : null); _enabledCached = obj != null && (bool)_isEnabled.GetValue(obj, null); } catch { _enabledCached = false; } return _enabledCached; } public static void Enter(GameCamera cam, Player player) { _isFirstPerson.SetValue(null, true); object[] parameters = new object[2] { cam, player }; _setupFP.Invoke(null, parameters); } public static void Exit(GameCamera cam, Player player) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) _isFirstPerson.SetValue(null, false); cam.m_3rdOffset = (Vector3)_saved3rd.GetValue(null); cam.m_fpsOffset = (Vector3)_savedFps.GetValue(null); cam.m_minDistance = (float)_minDist.GetValue(null); cam.m_maxDistance = (float)_maxDist.GetValue(null); cam.m_zoomSens = (float)_zoomSens.GetValue(null); cam.m_fov = 65f; Transform val = Head.Invoke((Character)(object)player); if ((Object)(object)val != (Object)null) { val.localScale = Vector3.one; } if ((Object)(object)((Character)player).m_eye != (Object)null) { ((Character)player).m_eye.localScale = Vector3.one; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] public static class CameraPatch { private static readonly FieldRef<GameCamera, float> Distance = AccessTools.FieldRefAccess<GameCamera, float>("m_distance"); private static readonly FieldRef<GameCamera, bool> FreeFly = AccessTools.FieldRefAccess<GameCamera, bool>("m_freeFly"); private static float _lastSwitch = -999f; private static bool _failed; [HarmonyPrefix] public static void Prefix(GameCamera __instance) { if (_failed || !ScrollToFirstPersonPlugin.Enabled.Value) { return; } try { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || FreeFly.Invoke(__instance) || !VPlus.FeatureEnabled()) { return; } float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (mouseScrollWheel == 0f || Time.unscaledTime - _lastSwitch < Mathf.Max(0f, ScrollToFirstPersonPlugin.Cooldown.Value) || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || InventoryGui.IsVisible() || StoreGui.IsVisible() || Menu.IsVisible() || Minimap.IsOpen() || Hud.IsPieceSelectionVisible() || Hud.InRadial() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).InPlaceMode()) { return; } if (!VPlus.IsFirstPerson) { if (mouseScrollWheel > 0f && Distance.Invoke(__instance) <= __instance.m_minDistance + 0.01f) { VPlus.Enter(__instance, localPlayer); _lastSwitch = Time.unscaledTime; } } else if (mouseScrollWheel < 0f) { VPlus.Exit(__instance, localPlayer); Distance.Invoke(__instance) = __instance.m_minDistance; _lastSwitch = Time.unscaledTime; } } catch (Exception ex) { _failed = true; ScrollToFirstPersonPlugin.Log.LogWarning((object)("Scroll switching disabled after an error: " + ex)); } } } [HarmonyPatch(typeof(Player), "AlwaysRotateCamera")] public static class FacePatch { [HarmonyPostfix] public static void Postfix(Player __instance, ref bool __result) { if (__result) { return; } try { if (ScrollToFirstPersonPlugin.FaceLook.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Character)__instance).InEmote() && !((Character)__instance).IsAttached() && (!ScrollToFirstPersonPlugin.FaceLookOnlyFirstPerson.Value || (ScrollToFirstPersonPlugin.VPlusReady && VPlus.IsFirstPerson))) { __result = true; } } catch { } } }