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 FishingEnhanced Spears Bows Harpoons v1.0.2
FishingEnhanced.dll
Decompiled 6 days agousing System; using System.Collections; 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.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FishingEnhanced")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("FishingEnhanced")] [assembly: AssemblyTitle("FishingEnhanced")] [assembly: AssemblyVersion("1.0.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 FishingEnhanced { internal static class FishingTweaks { internal static ConfigEntry<float> ReelSpeedMultiplier; internal static ConfigEntry<float> StaminaMultiplier; internal static ConfigEntry<float> LureRangeMultiplier; internal static ConfigEntry<float> HookChanceMultiplier; internal static ConfigEntry<bool> LureAssist; internal static ConfigEntry<float> LureAssistRange; internal static readonly ManualLogSource Log = Logger.CreateLogSource("FishingEnhanced.Tweaks"); internal static readonly string[] FloatReelFields = new string[2] { "m_pullLineSpeed", "m_moveForce" }; internal static readonly string[] FloatRangeFields = new string[1] { "m_range" }; internal static readonly string[] FishHookFields = new string[1] { "m_baseHookChance" }; private static readonly HashSet<string> Logged = new HashSet<string>(); internal static void BindConfig(ConfigFile config) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown ReelSpeedMultiplier = config.Bind<float>("3 - Fishing Rod", "ReelSpeedMultiplier", 2f, new ConfigDescription("Multiplier for how fast the rod reels in the line (1 = vanilla).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); StaminaMultiplier = config.Bind<float>("3 - Fishing Rod", "StaminaMultiplier", 0.5f, new ConfigDescription("Multiplier for stamina used while reeling / fighting a fish (0 = free, 1 = vanilla).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); LureRangeMultiplier = config.Bind<float>("4 - Lure", "LureRangeMultiplier", 4f, new ConfigDescription("Multiplier for how far away fish notice the bait (1 = vanilla).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); HookChanceMultiplier = config.Bind<float>("4 - Lure", "HookChanceMultiplier", 3f, new ConfigDescription("Multiplier for the chance a fish bites the bait (capped at 100%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); LureAssist = config.Bind<bool>("4 - Lure", "LureAssist", true, "Actively steer nearby fish toward your bait while it's in the water."); LureAssistRange = config.Bind<float>("4 - Lure", "LureAssistRange", 25f, new ConfigDescription("Radius (m) around the bait that LureAssist pulls fish from.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>())); GameObject val = new GameObject("FishingEnhanced_LureAssist"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<LureAssistRunner>(); } internal static int Scale(object obj, string[] names, float mult, float? max = null) { int num = 0; foreach (string text in names) { FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), text); if (!(fieldInfo == null) && !(fieldInfo.FieldType != typeof(float))) { float num2 = (float)fieldInfo.GetValue(obj) * mult; if (max.HasValue) { num2 = Mathf.Min(num2, max.Value); } fieldInfo.SetValue(obj, num2); num++; } } if (num == 0) { LogMissingOnce(obj.GetType(), names); } return num; } internal static void ScaleBaitChances(Fish fish, float mult) { if (!(AccessTools.Field(typeof(Fish), "m_baits")?.GetValue(fish) is IList list)) { return; } foreach (object item in list) { if (item != null) { FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "m_chance"); if (!(fieldInfo == null) && !(fieldInfo.FieldType != typeof(float))) { fieldInfo.SetValue(item, Mathf.Min((float)fieldInfo.GetValue(item) * mult, 1f)); } } } } private static void LogMissingOnce(Type type, string[] names) { string item = type.Name + ":" + string.Join(",", names); if (Logged.Add(item)) { IEnumerable<string> values = from f in AccessTools.GetDeclaredFields(type) where f.FieldType == typeof(float) select f.Name; Log.LogWarning((object)("None of [" + string.Join(", ", names) + "] found on " + type.Name + ". Available float fields: " + string.Join(", ", values))); } } } [HarmonyPatch] internal static class FishingFloat_Awake_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(FishingFloat), "Awake", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(FishingFloat), "Start", (Type[])null, (Type[])null); } private static void Postfix(FishingFloat __instance) { if (Plugin.Enabled.Value) { FishingTweaks.Scale(__instance, FishingTweaks.FloatReelFields, FishingTweaks.ReelSpeedMultiplier.Value); FishingTweaks.Scale(__instance, FishingTweaks.FloatRangeFields, FishingTweaks.LureRangeMultiplier.Value); } } } [HarmonyPatch(typeof(FishingFloat), "FixedUpdate")] internal static class FishingFloat_FixedUpdate_Patch { internal static bool InFloatUpdate; private static void Prefix() { InFloatUpdate = true; } private static void Finalizer() { InFloatUpdate = false; } } [HarmonyPatch] internal static class Player_UseStamina_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Player), "UseStamina", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Character), "UseStamina", (Type[])null, (Type[])null); } private static void Prefix(Character __instance, ref float __0) { if (Plugin.Enabled.Value && FishingFloat_FixedUpdate_Patch.InFloatUpdate && (object)__instance == Player.m_localPlayer) { __0 *= FishingTweaks.StaminaMultiplier.Value; } } } [HarmonyPatch] internal static class Fish_Awake_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Fish), "Awake", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Fish), "Start", (Type[])null, (Type[])null); } private static void Postfix(Fish __instance) { if (Plugin.Enabled.Value) { FishingTweaks.Scale(__instance, FishingTweaks.FishHookFields, FishingTweaks.HookChanceMultiplier.Value, 1f); FishingTweaks.ScaleBaitChances(__instance, FishingTweaks.HookChanceMultiplier.Value); } } } internal class LureAssistRunner : MonoBehaviour { private static readonly MethodInfo FloatGetCatch = AccessTools.Method(typeof(FishingFloat), "GetCatch", (Type[])null, (Type[])null); private static readonly FieldInfo FishWaypoint = AccessTools.Field(typeof(Fish), "m_waypoint"); private static readonly FieldInfo FishHaveWaypoint = AccessTools.Field(typeof(Fish), "m_haveWaypoint"); private static readonly MethodInfo FishIsHooked = AccessTools.Method(typeof(Fish), "IsHooked", (Type[])null, (Type[])null); private static readonly MethodInfo GetLiquidLevel = AccessTools.Method(typeof(Floating), "GetLiquidLevel", new Type[3] { typeof(Vector3), typeof(float), typeof(LiquidType) }, (Type[])null); private const float SettleTime = 1f; private readonly Dictionary<int, float> _settled = new Dictionary<int, float>(); private float _timer; private bool _warned; private static float WaterLevelAt(Vector3 pos) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (GetLiquidLevel != null) { try { return (float)GetLiquidLevel.Invoke(null, new object[3] { pos, 1f, (object)(LiquidType)0 }); } catch { } } return ((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f; } private bool BaitInWater(FishingFloat ff) { //IL_0007: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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 position = ((Component)ff).transform.position; float num = WaterLevelAt(position); if (position.y > num + 0.4f || position.y < num - 1.5f) { return false; } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetSolidHeight(position) > num - 0.5f) { return false; } Rigidbody component = ((Component)ff).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null && Mathf.Abs(component.linearVelocity.y) > 1.5f) { return false; } int instanceID = ((Object)ff).GetInstanceID(); if (!_settled.TryGetValue(instanceID, out var value)) { _settled[instanceID] = Time.time; return false; } return Time.time - value >= 1f; } private void Update() { //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !FishingTweaks.LureAssist.Value || (_timer -= Time.deltaTime) > 0f) { return; } _timer = 0.5f; if (FishWaypoint == null || FishHaveWaypoint == null) { if (!_warned) { _warned = true; FishingTweaks.Log.LogWarning((object)"LureAssist disabled: Fish waypoint fields not found (game update?)."); } return; } FishingFloat[] array = Object.FindObjectsByType<FishingFloat>((FindObjectsSortMode)0); if (array.Length == 0) { _settled.Clear(); return; } Fish[] array2 = Object.FindObjectsByType<Fish>((FindObjectsSortMode)0); float value = FishingTweaks.LureAssistRange.Value; FishingFloat[] array3 = array; foreach (FishingFloat val in array3) { if ((Object)(object)val == (Object)null) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { continue; } if (!BaitInWater(val)) { _settled.Remove(((Object)val).GetInstanceID()); } else { if (FloatGetCatch != null && FloatGetCatch.Invoke(val, null) != null) { continue; } Vector3 val2 = ((Component)val).transform.position + Vector3.down * 0.5f; Fish[] array4 = array2; foreach (Fish val3 in array4) { if (!((Object)(object)val3 == (Object)null) && Plugin.IsInWater(val3) && (!(FishIsHooked != null) || !(bool)FishIsHooked.Invoke(val3, null)) && !(Vector3.Distance(((Component)val3).transform.position, val2) > value)) { ZNetView component2 = ((Component)val3).GetComponent<ZNetView>(); if (!((Object)(object)component2 == (Object)null) && component2.IsValid() && component2.IsOwner()) { FishWaypoint.SetValue(val3, val2); FishHaveWaypoint.SetValue(val3, true); } } } } } } } [BepInPlugin("com.matthew.valheim.fishingenhanced", "Fishing Enhanced", "1.0.1")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "com.matthew.valheim.fishingenhanced"; public const string ModName = "Fishing Enhanced"; public const string ModVersion = "1.0.1"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> PickupRange; internal static ConfigEntry<float> AimTolerance; private static MethodInfo _pickupMethod; private static MethodInfo _isOutOfWaterMethod; internal static Plugin Instance; private Harmony _harmony; private void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Allow picking up fish with the Use key while they are swimming in water."); PickupRange = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "PickupRange", 2.5f, new ConfigDescription("Max distance (m) for the fallback in-water pickup.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), Array.Empty<object>())); AimTolerance = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "AimTolerance", 0.5f, new ConfigDescription("How directly you must face the fish for the fallback pickup (1 = dead center, 0 = 90° cone).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _pickupMethod = AccessTools.Method(typeof(Fish), "Pickup", new Type[1] { typeof(Humanoid) }, (Type[])null); _isOutOfWaterMethod = AccessTools.Method(typeof(Fish), "IsOutOfWater", (Type[])null, (Type[])null); if (_pickupMethod == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Fish.Pickup(Humanoid) not found - game update may have changed it."); } if (_isOutOfWaterMethod == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Fish.IsOutOfWater() not found - game update may have changed it."); } Instance = this; WeaponCatch.BindConfig(((BaseUnityPlugin)this).Config); FishingTweaks.BindConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.matthew.valheim.fishingenhanced"); _harmony.PatchAll(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static bool IsInWater(Fish fish) { if ((Object)(object)fish == (Object)null || _isOutOfWaterMethod == null) { return false; } return !(bool)_isOutOfWaterMethod.Invoke(fish, null); } internal static bool TryPickup(Fish fish, Humanoid character) { if ((Object)(object)fish == (Object)null || (Object)(object)character == (Object)null || _pickupMethod == null) { return false; } object obj = _pickupMethod.Invoke(fish, new object[1] { character }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = ((1 == 0) ? 1 : 0); } else { num = 1; } return (byte)((uint)num | (flag ? 1u : 0u)) != 0; } private void Update() { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) if (!Enabled.Value) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || (!ZInput.GetButtonDown("Use") && !ZInput.GetButtonDown("JoyUse")) || (Object)(object)((Humanoid)localPlayer).GetHoverObject() != (Object)null || InventoryGui.IsVisible() || Menu.IsVisible() || Minimap.IsOpen() || Console.IsVisible() || TextInput.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())) { return; } Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : null); if ((Object)(object)val == (Object)null) { return; } Vector3 val2 = ((Component)localPlayer).transform.position + Vector3.up; Fish val3 = null; float num = float.MaxValue; Fish[] array = Object.FindObjectsByType<Fish>((FindObjectsSortMode)0); foreach (Fish val4 in array) { if (!IsInWater(val4)) { continue; } Vector3 position = ((Component)val4).transform.position; float num2 = Vector3.Distance(val2, position); if (num2 > PickupRange.Value) { continue; } Vector3 forward = val.forward; Vector3 val5 = position - val.position; float num3 = Vector3.Dot(forward, ((Vector3)(ref val5)).normalized); if (!(num3 < AimTolerance.Value)) { float num4 = num2 - num3; if (num4 < num) { num = num4; val3 = val4; } } } if ((Object)(object)val3 != (Object)null) { TryPickup(val3, (Humanoid)(object)localPlayer); } } } [HarmonyPatch(typeof(Fish), "Interact")] internal static class Fish_Interact_Patch { private static bool Prefix(Fish __instance, Humanoid __0, bool __1, ref bool __result) { if (!Plugin.Enabled.Value || __1 || !Plugin.IsInWater(__instance)) { return true; } __result = Plugin.TryPickup(__instance, __0); return false; } } [HarmonyPatch(typeof(Fish), "GetHoverText")] internal static class Fish_GetHoverText_Patch { private static void Postfix(Fish __instance, ref string __result) { if (Plugin.Enabled.Value && Plugin.IsInWater(__instance)) { __result = Localization.instance.Localize(__instance.GetHoverName() + "\n[<color=yellow><b>$KEY_Use</b></color>] $inventory_pickup"); } } } internal enum CatchType { None, HarpoonPull, ToInventory } internal static class WeaponCatch { internal static ConfigEntry<bool> HarpoonPullEnabled; internal static ConfigEntry<bool> ProjectileCatchEnabled; internal static ConfigEntry<float> HitRadius; internal static ConfigEntry<float> PullDuration; internal static ConfigEntry<string> HarpoonPrefabs; private static readonly FieldInfo OwnerField = AccessTools.Field(typeof(Projectile), "m_owner"); private static readonly FieldInfo WeaponField = AccessTools.Field(typeof(Projectile), "m_weapon"); private static readonly FieldInfo SkillField = AccessTools.Field(typeof(Projectile), "m_skill"); private static readonly Dictionary<Projectile, Vector3> LastPos = new Dictionary<Projectile, Vector3>(); private static readonly HashSet<int> SpentProjectiles = new HashSet<int>(); private static readonly HashSet<int> FishInFlight = new HashSet<int>(); private static MonoBehaviour _runner; private static MonoBehaviour Runner { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_runner == (Object)null) { GameObject val = new GameObject("FishingEnhanced_CoroutineRunner"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; _runner = (MonoBehaviour)(object)val.AddComponent<CoroutineRunner>(); } return _runner; } } internal static void BindConfig(ConfigFile config) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown HarpoonPullEnabled = config.Bind<bool>("2 - Weapon Catching", "HarpoonPull", true, "Hitting a fish with a harpoon pulls it to your feet."); ProjectileCatchEnabled = config.Bind<bool>("2 - Weapon Catching", "SpearAndBowCatch", true, "Hitting a fish with a thrown spear or a bow arrow puts it straight into your inventory."); HitRadius = config.Bind<float>("2 - Weapon Catching", "HitRadius", 0.6f, new ConfigDescription("How close (m) a projectile must pass to a fish to count as a hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())); PullDuration = config.Bind<float>("2 - Weapon Catching", "PullDuration", 0.35f, new ConfigDescription("Seconds the harpoon takes to drag the fish to you (0 = instant).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); HarpoonPrefabs = config.Bind<string>("2 - Weapon Catching", "HarpoonPrefabs", "SpearChitin", "Comma-separated item prefab names treated as harpoons (SpearChitin = Abyssal Harpoon)."); } private static bool IsLocalShot(Projectile p) { return (Object)(object)p != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && OwnerField != null && OwnerField.GetValue(p) == Player.m_localPlayer; } internal static CatchType Classify(Projectile p) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Invalid comparison between Unknown and I4 //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Invalid comparison between Unknown and I4 //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Invalid comparison between Unknown and I4 object? obj = WeaponField?.GetValue(p); ItemData val = (ItemData)((obj is ItemData) ? obj : null); string value = (((Object)(object)val?.m_dropPrefab != (Object)null) ? ((Object)val.m_dropPrefab).name : ""); IEnumerable<string> source = from s in HarpoonPrefabs.Value.Split(',') select s.Trim() into s where s.Length > 0 select s; if (source.Contains<string>(value, StringComparer.OrdinalIgnoreCase) || ((Object)p).name.IndexOf("harpoon", StringComparison.OrdinalIgnoreCase) >= 0) { return HarpoonPullEnabled.Value ? CatchType.HarpoonPull : CatchType.None; } SkillType val2 = (SkillType)((val == null) ? ((SkillField != null) ? ((int)(SkillType)SkillField.GetValue(p)) : 0) : ((int)val.m_shared.m_skillType)); if ((int)val2 == 5 || (int)val2 == 8) { return ProjectileCatchEnabled.Value ? CatchType.ToInventory : CatchType.None; } return CatchType.None; } private static Fish FindFish(Collider c) { return ((Object)(object)c != (Object)null) ? ((Component)c).GetComponentInParent<Fish>() : null; } private static Fish NearestFish(Vector3 point, float radius) { //IL_0006: 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_003b: Unknown result type (might be due to invalid IL or missing references) Fish result = null; float num = radius; Collider[] array = Physics.OverlapSphere(point, radius, -1, (QueryTriggerInteraction)2); foreach (Collider c in array) { Fish val = FindFish(c); if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.Distance(point, ((Component)val).transform.position); if (num2 <= num) { num = num2; result = val; } } } return result; } internal static void TryCatch(Projectile p, Fish fish) { if ((Object)(object)fish == (Object)null || !Plugin.Enabled.Value || SpentProjectiles.Contains(((Object)p).GetInstanceID()) || FishInFlight.Contains(((Object)fish).GetInstanceID())) { return; } CatchType catchType = Classify(p); if (catchType != CatchType.None) { SpentProjectiles.Add(((Object)p).GetInstanceID()); Player localPlayer = Player.m_localPlayer; if (catchType != CatchType.ToInventory || !Plugin.TryPickup(fish, (Humanoid)(object)localPlayer)) { Runner.StartCoroutine(PullToPlayer(fish, localPlayer)); } } } private static IEnumerator PullToPlayer(Fish fish, Player player) { int id = ((Object)fish).GetInstanceID(); FishInFlight.Add(id); ZNetView nview = ((Component)fish).GetComponent<ZNetView>(); if ((Object)(object)nview != (Object)null && nview.IsValid()) { nview.ClaimOwnership(); } Rigidbody body = ((Component)fish).GetComponent<Rigidbody>(); bool wasKinematic = (Object)(object)body != (Object)null && body.isKinematic; if ((Object)(object)body != (Object)null) { body.isKinematic = true; } ((Behaviour)fish).enabled = false; Vector3 start = ((Component)fish).transform.position; float duration = PullDuration.Value; float t = 0f; while (duration > 0f && t < 1f && (Object)(object)fish != (Object)null && (Object)(object)player != (Object)null) { t += Time.deltaTime / duration; Vector3 target = ((Component)player).transform.position + Vector3.up * 0.3f; ((Component)fish).transform.position = Vector3.Lerp(start, target, t); yield return null; } if ((Object)(object)fish != (Object)null) { if ((Object)(object)player != (Object)null) { ((Component)fish).transform.position = ((Component)player).transform.position + Vector3.up * 0.3f; } if ((Object)(object)body != (Object)null) { body.isKinematic = wasKinematic; body.linearVelocity = Vector3.zero; body.angularVelocity = Vector3.zero; } ((Behaviour)fish).enabled = true; } FishInFlight.Remove(id); } internal static void SweepCheck(Projectile p) { //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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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) if (!Plugin.Enabled.Value || !IsLocalShot(p) || SpentProjectiles.Contains(((Object)p).GetInstanceID())) { return; } Vector3 position = ((Component)p).transform.position; if (LastPos.TryGetValue(p, out var value)) { Vector3 val = position - value; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude > 0.001f) { foreach (RaycastHit item in from h in Physics.SphereCastAll(value, HitRadius.Value, val / magnitude, magnitude, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; Fish val2 = FindFish(((RaycastHit)(ref current)).collider); if ((Object)(object)val2 == (Object)null) { continue; } TryCatch(p, val2); break; } } } LastPos[p] = position; if (LastPos.Count > 256) { Prune(); } } private static void Prune() { foreach (Projectile item in LastPos.Keys.Where((Projectile k) => (Object)(object)k == (Object)null).ToList()) { LastPos.Remove(item); } if (SpentProjectiles.Count > 1024) { SpentProjectiles.Clear(); } } internal static void OnProjectileHit(Projectile p, object[] args) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !IsLocalShot(p)) { return; } Collider c = args.OfType<Collider>().FirstOrDefault(); Fish val = FindFish(c); if ((Object)(object)val == (Object)null) { Vector3 point = ((args.FirstOrDefault((object a) => a is Vector3) is Vector3 val2) ? val2 : ((Component)p).transform.position); val = NearestFish(point, HitRadius.Value); } TryCatch(p, val); LastPos.Remove(p); } } internal class CoroutineRunner : MonoBehaviour { } [HarmonyPatch(typeof(Projectile), "FixedUpdate")] internal static class Projectile_FixedUpdate_Patch { private static void Postfix(Projectile __instance) { WeaponCatch.SweepCheck(__instance); } } [HarmonyPatch(typeof(Projectile), "OnHit")] internal static class Projectile_OnHit_Patch { private static void Prefix(Projectile __instance, object[] __args) { WeaponCatch.OnProjectileHit(__instance, __args); } } }