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 CrossbowZoom v1.0.0
CrossbowZoom.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("CrossbowZoom")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+8e794e21c904e7dafcd4fb57c3a1626e3222ce85")] [assembly: AssemblyProduct("CrossbowZoom")] [assembly: AssemblyTitle("CrossbowZoom")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 CrossbowZoom { internal static class BetterArcheryBridge { public const string Guid = "ishid4.mods.betterarchery"; public static FieldRef<int> ZoomState = null; public static int ZoomingIn; public static FieldRef<float> ZoomInTimer = null; public static FieldRef<float> ZoomOutDelayTimer = null; public static FieldRef<float> BaseFov = null; public static FieldRef<float> LastZoomFov = null; public static FieldRef<float> NewZoomFov = null; public static ConfigEntry<bool> ZoomEnabled = null; public static ConfigEntry<bool> AutomaticZoom = null; public static ConfigEntry<float> ZoomFactor = null; public static ConfigEntry<float> ZoomConstantTime = null; public static Func<bool> IsZoomHeld = null; public static Func<Player, bool> TakesInput = null; public static string Version { get; private set; } = "not loaded"; public static bool TryResolve(out string problem) { if (!Chainloader.PluginInfos.TryGetValue("ishid4.mods.betterarchery", out var value) || (Object)(object)value.Instance == (Object)null) { problem = "plugin ishid4.mods.betterarchery is not loaded"; return false; } Version = value.Metadata.Version.ToString(); Type type = ((object)value.Instance).GetType().Assembly.GetType("BetterArchery.BetterArchery"); if (type == null) { problem = "type BetterArchery.BetterArchery not found"; return false; } try { Type type2 = AccessTools.Inner(type, "ZoomState") ?? throw new MissingMemberException(type.FullName, "ZoomState"); if (!type2.IsEnum || Enum.GetUnderlyingType(type2) != typeof(int)) { throw new MissingMemberException(type2.FullName + " is not an int enum"); } ZoomingIn = Convert.ToInt32(Enum.Parse(type2, "ZoomingIn")); ZoomState = Ref<int>(type, "__ZoomState", type2); ZoomInTimer = Ref<float>(type, "ZoomInTimer"); ZoomOutDelayTimer = Ref<float>(type, "ZoomOutDelayTimer"); BaseFov = Ref<float>(type, "__BaseFov"); LastZoomFov = Ref<float>(type, "__LastZoomFov"); NewZoomFov = Ref<float>(type, "__NewZoomFov"); ZoomEnabled = Entry<bool>(type, "ConfigBowZoomEnabled"); AutomaticZoom = Entry<bool>(type, "AutomaticBowZoom"); ZoomFactor = Entry<float>(type, "BowZoomFactor"); ZoomConstantTime = Entry<float>(type, "BowZoomConstantTime"); MethodInfo methodInfo = AccessTools.Method(type, "IsBowZoomHeld", Type.EmptyTypes, (Type[])null); if (methodInfo == null || !methodInfo.IsStatic || methodInfo.ReturnType != typeof(bool)) { throw new MissingMemberException(type.FullName, "static bool IsBowZoomHeld()"); } IsZoomHeld = AccessTools.MethodDelegate<Func<bool>>(methodInfo, (object)null, true); MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "TakeInput", Type.EmptyTypes, (Type[])null); if (methodInfo2 == null || methodInfo2.IsStatic || methodInfo2.ReturnType != typeof(bool)) { throw new MissingMemberException("Player", "bool TakeInput()"); } TakesInput = AccessTools.MethodDelegate<Func<Player, bool>>(methodInfo2, (object)null, true); } catch (Exception ex) { problem = ex.Message; return false; } problem = ""; return true; } private static FieldInfo StaticField(Type main, string name, Type expected) { FieldInfo fieldInfo = AccessTools.Field(main, name); if (fieldInfo == null || !fieldInfo.IsStatic || fieldInfo.FieldType != expected) { throw new MissingMemberException(main.FullName, "static " + expected.Name + " " + name); } return fieldInfo; } private static FieldRef<T> Ref<T>(Type main, string name, Type? fieldType = null) { return AccessTools.StaticFieldRefAccess<T>(StaticField(main, name, fieldType ?? typeof(T))); } private static ConfigEntry<T> Entry<T>(Type main, string name) { return ((ConfigEntry<T>)StaticField(main, name, typeof(ConfigEntry<T>)).GetValue(null)) ?? throw new MissingMemberException(main.FullName, name + " is not bound yet"); } } internal static class Patches { private static float zoomTime; private static bool ZoomingCrossbow(Player player) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !BetterArcheryBridge.TakesInput(player)) { return false; } if (!BetterArcheryBridge.ZoomEnabled.Value || BetterArcheryBridge.AutomaticZoom.Value) { return false; } ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon == null) { return false; } if (ZoomMath.IsCrossbow((int)currentWeapon.m_shared.m_itemType == 4, currentWeapon.m_shared.m_attack.m_requiresReload)) { return BetterArcheryBridge.IsZoomHeld(); } return false; } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] [HarmonyPostfix] [HarmonyPriority(-2)] private static void UpdateCrosshairPostfix(Player player) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (BetterArcheryBridge.BaseFov.Invoke() == 0f || !ZoomingCrossbow(player)) { zoomTime = 0f; return; } ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); zoomTime += Time.deltaTime; BetterArcheryBridge.ZoomInTimer.Invoke() = zoomTime; BetterArcheryBridge.ZoomOutDelayTimer.Invoke() = 0f; BetterArcheryBridge.ZoomState.Invoke() = BetterArcheryBridge.ZoomingIn; float num = ZoomMath.ZoomFov(BetterArcheryBridge.BaseFov.Invoke(), BetterArcheryBridge.ZoomFactor.Value, BetterArcheryBridge.ZoomConstantTime.Value, BetterArcheryBridge.ZoomInTimer.Invoke(), ((Character)player).GetSkillFactor(currentWeapon.m_shared.m_skillType)); BetterArcheryBridge.LastZoomFov.Invoke() = num; BetterArcheryBridge.NewZoomFov.Invoke() = num; GameCamera.instance.m_fov = num; } [HarmonyPatch(typeof(Player), "SetControls")] [HarmonyPrefix] private static void SetControlsPrefix(Player __instance, ref bool block, ref bool blockHold) { if ((block || blockHold) && __instance.GetDoodadController() == null && ZoomingCrossbow(__instance)) { block = false; blockHold = false; } } } [BepInPlugin("helix.crossbowzoom", "CrossbowZoom", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "helix.crossbowzoom"; public const string PluginName = "CrossbowZoom"; public const string PluginVersion = "1.0.0"; private void Awake() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!BetterArcheryBridge.TryResolve(out string problem)) { ((BaseUnityPlugin)this).Logger.LogError((object)("BetterArchery " + BetterArcheryBridge.Version + ": " + problem + ". Crossbow zoom is off; nothing was patched.")); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)("BetterArchery " + BetterArcheryBridge.Version + ": all zoom members bound.")); new Harmony("helix.crossbowzoom").PatchAll(typeof(Patches)); LogPostfixOrder(((BaseUnityPlugin)this).Logger); } } private static void LogPostfixOrder(ManualLogSource log) { MethodBase methodBase = AccessTools.Method(typeof(Hud), "UpdateCrosshair", (Type[])null, (Type[])null); Patch[] postfixes = (Patch[])(((object)Harmony.GetPatchInfo(methodBase)?.Postfixes.ToArray()) ?? ((object)new Patch[0])); List<MethodInfo> sortedPatchMethods = PatchProcessor.GetSortedPatchMethods(methodBase, postfixes); string text = string.Join(" -> ", sortedPatchMethods.Select(delegate(MethodInfo m) { Patch val = postfixes.First((Patch x) => x.PatchMethod == m); return $"{m.DeclaringType?.FullName}.{m.Name} (priority {val.priority})"; })); log.LogInfo((object)("Hud.UpdateCrosshair postfix order: " + text)); } } internal static class ZoomMath { public static bool IsCrossbow(bool isBowItemType, bool requiresReload) { return isBowItemType && requiresReload; } public static float ZoomFov(float baseFov, float factor, float constantTime, float zoomInTimer, float skillFactor) { float num = 2f * (1f - skillFactor); if (num <= 0.1f) { num = 0.1f; } float t = ((constantTime > 0f) ? InverseLerp(0.05f, constantTime, zoomInTimer) : InverseLerp(0.05f, num, zoomInTimer)); return Lerp(baseFov, baseFov / factor, t); } private static float Clamp01(float value) { if (!(value < 0f)) { if (!(value > 1f)) { return value; } return 1f; } return 0f; } private static float Lerp(float a, float b, float t) { return a + (b - a) * Clamp01(t); } private static float InverseLerp(float a, float b, float value) { if (a == b) { return 0f; } return Clamp01((value - a) / (b - a)); } } }