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 Trolling Fishing v1.0.5
TrollingFishing.dll
Decompiled 21 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("TrollingFishing")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyProduct("TrollingFishing")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("D50DC2B3-A9F3-4E91-83F5-B36EA9ECA08C")] [assembly: AssemblyFileVersion("1.0.5")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { private readonly string <Name>k__BackingField; public string Name => <Name>k__BackingField; public ExtensionMarkerAttribute(string name) { <Name>k__BackingField = name; } } } namespace TrollingFishing { internal static class AzuCraftyBoxesCompat { private const string AzuCraftyBoxesAssemblyName = "AzuCraftyBoxes"; private static bool _initialized; private static bool _loaded; private static bool _loggedAddFailure; private static bool _loggedRemoveFailure; private static bool _loggedAggressiveUnavailable; private static bool _loggedAggressiveFailure; private static bool _aggressiveRefreshFailed; private static MethodInfo? _addContainerMethod; private static MethodInfo? _removeContainerMethod; private static MethodInfo? _updateContainersMethod; private static FieldInfo? _queryFrameIdField; private static FieldInfo? _lastQueryTimeField; internal static bool IsLoaded() { return TryEnsureLoaded(); } internal static void AddContainer(Container container) { if ((Object)(object)container == (Object)null || TrollingFishingPlugin.FishingRodBagAzuCraftyBoxesCompatibility.Value.IsOff() || !TryEnsureLoaded()) { return; } try { _addContainerMethod?.Invoke(null, new object[1] { container }); } catch (Exception ex) { if (!_loggedAddFailure) { _loggedAddFailure = true; TrollingFishingPlugin.ModLogger.LogWarning((object)("Could not register fishing rod bag with AzuCraftyBoxes: " + ex.GetBaseException().Message)); } return; } TryAggressiveRefresh(); } internal static void RemoveContainer(Container container) { if ((Object)(object)container == (Object)null || !TryEnsureLoaded()) { return; } try { _removeContainerMethod?.Invoke(null, new object[1] { container }); } catch (Exception ex) { if (!_loggedRemoveFailure) { _loggedRemoveFailure = true; TrollingFishingPlugin.ModLogger.LogWarning((object)("Could not unregister fishing rod bag from AzuCraftyBoxes: " + ex.GetBaseException().Message)); } return; } TryAggressiveRefresh(); } private static bool TryEnsureLoaded() { if (_initialized) { return _loaded; } _initialized = true; Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly candidate) => string.Equals(candidate.GetName().Name, "AzuCraftyBoxes", StringComparison.OrdinalIgnoreCase)); Type type = assembly?.GetType("AzuCraftyBoxes.API"); _addContainerMethod = type?.GetMethod("AddContainer", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Container) }, null); _removeContainerMethod = type?.GetMethod("RemoveContainer", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Container) }, null); Type type2 = assembly?.GetType("AzuCraftyBoxes.Util.Functions.Boxes"); _updateContainersMethod = type2?.GetMethod("UpdateContainers", BindingFlags.Static | BindingFlags.NonPublic); _queryFrameIdField = (assembly?.GetType("AzuCraftyBoxes.Util.Functions.Boxes+QueryFrame"))?.GetField("FrameId", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _lastQueryTimeField = type2?.GetField("_lastQueryTime", BindingFlags.Static | BindingFlags.NonPublic); _loaded = _addContainerMethod != null && _removeContainerMethod != null; if (_loaded) { TrollingFishingPlugin.ModLogger.LogInfo((object)"AzuCraftyBoxes compatibility enabled for fishing rod bags."); } return _loaded; } private static void TryAggressiveRefresh() { if (TrollingFishingPlugin.FishingRodBagAzuCraftyBoxesAggressiveRefresh.Value.IsOff() || _aggressiveRefreshFailed) { return; } if (_updateContainersMethod == null && _queryFrameIdField == null && _lastQueryTimeField == null) { if (!_loggedAggressiveUnavailable) { _loggedAggressiveUnavailable = true; TrollingFishingPlugin.ModLogger.LogWarning((object)"AzuCraftyBoxes aggressive refresh is enabled, but private refresh hooks were not found. Falling back to public API only."); } return; } try { _updateContainersMethod?.Invoke(null, Array.Empty<object>()); _queryFrameIdField?.SetValue(null, -1); _lastQueryTimeField?.SetValue(null, -999f); } catch (Exception ex) { _aggressiveRefreshFailed = true; if (!_loggedAggressiveFailure) { _loggedAggressiveFailure = true; TrollingFishingPlugin.ModLogger.LogWarning((object)("AzuCraftyBoxes aggressive refresh failed and was disabled for this session; public API compatibility remains active: " + ex.GetBaseException().Message)); } } } } internal static class FishingOverrideSystem { internal sealed class FishingRodBagProxyContainer : MonoBehaviour { private Player? _player; private ItemData? _rod; private Inventory? _inventory; private Container? _container; private bool _closed; internal void Initialize(Player player, ItemData rod, Container container, int slots, int width, int height) { _player = player; _rod = rod; _container = container; container.m_name = "$item_fishingrod"; container.m_width = width; container.m_height = height; container.m_inUse = false; rod.m_customData["TrollingFishing.FishingRodBag.Slots"] = slots.ToString(CultureInfo.InvariantCulture); LoadInventory(width, height); AzuCraftyBoxesCompat.AddContainer(container); } internal void SetPlayer(Player player) { _player = player; } internal void ReloadFromRod() { if (!_closed && !((Object)(object)_player == (Object)null) && _rod != null && !((Object)(object)_container == (Object)null)) { ResolveGridSize(ResolveTargetSlotCount(_player, _rod), out var width, out var height); _container.m_width = width; _container.m_height = height; LoadInventory(width, height); } } private void LoadInventory(int width, int height) { if (_rod != null && !((Object)(object)_container == (Object)null)) { if (_inventory != null) { Inventory? inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(Save)); UnregisterFishingRodBagInventory(_inventory); } _inventory = (((Object)(object)_player != (Object)null) ? LoadFishingRodBagInventory(_player, _rod, out width, out height) : CreateFishingRodBagInventory(_rod, width, height)); Inventory? inventory2 = _inventory; inventory2.m_onChanged = (Action)Delegate.Combine(inventory2.m_onChanged, new Action(Save)); RegisterFishingRodBagInventory(_inventory, _rod); _container.m_width = width; _container.m_height = height; _container.m_inventory = _inventory; } } private void Update() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_player != (Object)null) { ((Component)this).transform.position = ((Component)_player).transform.position; } } internal void Save() { if (_rod != null && _inventory != null) { SaveFishingRodBagInventory(_rod, _inventory, refreshProxy: false); } } internal void CloseAndDestroy() { if (!_closed) { Cleanup(); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { Cleanup(); } private void Cleanup() { if (!_closed) { _closed = true; Save(); if (_inventory != null) { Inventory? inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(Save)); UnregisterFishingRodBagInventory(_inventory); } if ((Object)(object)_container != (Object)null) { AzuCraftyBoxesCompat.RemoveContainer(_container); } } } } internal sealed class FishingRodBagContainer : MonoBehaviour { private Player? _player; private ItemData? _rod; private Inventory? _inventory; private Container? _container; private bool _closed; internal void Initialize(Player player, ItemData rod, Container container, int slots, int width, int height) { _player = player; _rod = rod; _container = container; _inventory = LoadFishingRodBagInventory(player, rod, out width, out height); Inventory? inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(Save)); RegisterFishingRodBagInventory(_inventory, rod); container.m_name = "$item_fishingrod"; container.m_width = width; container.m_height = height; container.m_inventory = _inventory; container.m_inUse = true; AzuCraftyBoxesCompat.AddContainer(container); rod.m_customData["TrollingFishing.FishingRodBag.Slots"] = slots.ToString(CultureInfo.InvariantCulture); Save(); } private void Update() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!_closed && (Object)(object)_container != (Object)null && (Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_currentContainer != (Object)(object)_container) { CloseAndDestroy(); } else if ((Object)(object)_player != (Object)null) { ((Component)this).transform.position = ((Component)_player).transform.position; } } internal void Save() { if (_rod != null && _inventory != null) { SaveFishingRodBagInventory(_rod, _inventory); } } internal void CloseAndDestroy() { if (!_closed) { _closed = true; Save(); if (_rod != null) { FishingRodBagUiState.OpenRods.Remove(_rod); } if (_inventory != null) { Inventory? inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(Save)); UnregisterFishingRodBagInventory(_inventory); } if ((Object)(object)_container != (Object)null) { AzuCraftyBoxesCompat.RemoveContainer(_container); } Object.Destroy((Object)(object)((Component)this).gameObject); } } } internal readonly struct ExtraDropChanceState { internal readonly DropTable? DropTable; internal readonly float OriginalDropChance; internal ExtraDropChanceState(DropTable dropTable, float originalDropChance) { DropTable = dropTable; OriginalDropChance = originalDropChance; } } internal enum FishingRodAmmoSource { Inventory, FishingRodBag } internal readonly struct FishingRodAmmoSelection { internal readonly ItemData AmmoItem; internal readonly FishingRodAmmoSource Source; internal bool IsValid => AmmoItem != null; internal FishingRodAmmoSelection(ItemData ammoItem, FishingRodAmmoSource source) { AmmoItem = ammoItem; Source = source; } } internal readonly struct MultiLineBaitReservation { internal readonly string PrefabName; internal readonly bool FromRodBag; internal readonly ItemData? Rod; internal bool IsValid => !string.IsNullOrWhiteSpace(PrefabName); internal MultiLineBaitReservation(string prefabName, bool fromRodBag, ItemData? rod = null) { PrefabName = prefabName ?? ""; FromRodBag = fromRodBag; Rod = rod; } } internal readonly struct MultiLineFishingSetupContext { internal static readonly MultiLineFishingSetupContext Empty = new MultiLineFishingSetupContext(null, null, 0, 0, default(MultiLineBaitReservation), default(MultiLineBaitReservation)); internal readonly Character? Owner; internal readonly ItemData? Rod; internal readonly int LineIndex; internal readonly int PrimaryEquivalentLineIndex; internal readonly MultiLineBaitReservation ReservedBait; internal readonly MultiLineBaitReservation BaitReturnSource; internal readonly bool ConsumeTrackedBaitOnSetup; internal MultiLineFishingSetupContext(Character? owner, ItemData? rod, int lineIndex, int primaryEquivalentLineIndex, MultiLineBaitReservation reservedBait, MultiLineBaitReservation baitReturnSource, bool consumeTrackedBaitOnSetup = false) { Owner = owner; Rod = rod; LineIndex = Mathf.Max(0, lineIndex); PrimaryEquivalentLineIndex = Mathf.Max(0, primaryEquivalentLineIndex); ReservedBait = reservedBait; BaitReturnSource = baitReturnSource; ConsumeTrackedBaitOnSetup = consumeTrackedBaitOnSetup; } } internal readonly struct MultiLineFishingUpdateContext { internal readonly Character Owner; internal readonly float StaminaFactor; internal readonly float SkillRaiseFactor; internal MultiLineFishingUpdateContext(Character owner, float staminaFactor, float skillRaiseFactor) { Owner = owner; StaminaFactor = staminaFactor; SkillRaiseFactor = skillRaiseFactor; } } private sealed class MultiLineFishingSetupScope : IDisposable { public void Dispose() { MultiLineFishingCastState.SetupDepth = Mathf.Max(0, MultiLineFishingCastState.SetupDepth - 1); if (MultiLineFishingCastState.SetupContexts.Count > 0) { MultiLineFishingCastState.SetupContexts.RemoveAt(MultiLineFishingCastState.SetupContexts.Count - 1); } } } private sealed class BaitReturnSetupScope : IDisposable { private readonly Attack? _attack; internal BaitReturnSetupScope(Attack? attack) { _attack = attack; } public void Dispose() { if (BaitSourceTrackerState.SetupContexts.Count > 0) { BaitSourceTrackerState.SetupContexts.RemoveAt(BaitSourceTrackerState.SetupContexts.Count - 1); } if (_attack != null) { BaitSourceTrackerState.AttackSources.Remove(_attack); } } } private sealed class MultiLineFishingUpdateScope : IDisposable { public void Dispose() { if (MultiLineFishingCastState.UpdateContexts.Count > 0) { MultiLineFishingCastState.UpdateContexts.RemoveAt(MultiLineFishingCastState.UpdateContexts.Count - 1); } } } private sealed class MultiLineFishingFloatMarker : MonoBehaviour { private Character? _owner; private ItemData? _rod; private float _ignoreAttackUntil; private int _lineIndex; private int _primaryEquivalentLineIndex; private MultiLineBaitReservation _reservedBait; private MultiLineBaitReservation _baitReturnSource; private bool _initialAttackEnded; private bool _loggedInitialAttackSkip; internal Character? Owner => _owner; internal ItemData? Rod => _rod; internal int LineIndex => _lineIndex; internal int PrimaryEquivalentLineIndex => _primaryEquivalentLineIndex; internal bool IsAdditionalLine => _lineIndex != _primaryEquivalentLineIndex; internal MultiLineBaitReservation ReservedBait => _reservedBait; internal MultiLineBaitReservation BaitReturnSource => _baitReturnSource; internal void Initialize(Character owner, ItemData? rod, float ignoreAttackUntil, int lineIndex, int primaryEquivalentLineIndex, MultiLineBaitReservation reservedBait, MultiLineBaitReservation baitReturnSource) { _owner = owner; _rod = rod; _ignoreAttackUntil = ignoreAttackUntil; _lineIndex = Mathf.Max(0, lineIndex); _primaryEquivalentLineIndex = Mathf.Max(0, primaryEquivalentLineIndex); _reservedBait = reservedBait; _baitReturnSource = baitReturnSource; _initialAttackEnded = false; _loggedInitialAttackSkip = false; } internal bool ShouldSkipAttackCancellation() { if ((Object)(object)_owner == (Object)null) { return false; } if (!_owner.InAttack() && !_owner.IsDrawingBow()) { _initialAttackEnded = true; return false; } if (_initialAttackEnded || Time.time > _ignoreAttackUntil) { return false; } if (!_loggedInitialAttackSkip) { _loggedInitialAttackSkip = true; TrollingFishingPlugin.LogDebug("[Fishing multiLine] suppressing initial cast cancellation object=" + ((Object)((Component)this).gameObject).name + "."); } return true; } } private sealed class FishingBaitReturnTracker : MonoBehaviour { private MultiLineBaitReservation _source; private bool _settled; internal MultiLineBaitReservation Source => _source; internal bool IsSettled => _settled; internal void Initialize(MultiLineBaitReservation source, bool settled = false) { _source = source; _settled = !source.IsValid || settled; } internal bool TrySettle() { if (_settled) { return false; } _settled = true; return true; } } private static readonly Dictionary<FishingFloat, float> FishingFloatOwnerSkillFactorCache = new Dictionary<FishingFloat, float>(); private static int _fishingFloatOwnerSkillFactorCacheFrame = -1; private static readonly FieldInfo? FishingFloatBaitConsumedField = AccessTools.Field(typeof(FishingFloat), "m_baitConsumed"); private static readonly FieldInfo? InventoryGridElementsField = AccessTools.Field(typeof(InventoryGrid), "m_elements"); private static readonly MethodInfo? InventoryGuiCloseContainerMethod = AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null); internal static int CountAvailableAmmo(Humanoid humanoid, ItemData weapon, string ammoType) { int num = CountAmmo(humanoid.GetInventory(), ammoType); if (TrollingFishingPlugin.FishingRodBag.Value.IsOn()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && IsFishingRod(weapon)) { num += CountFishingRodBagAmmo(val, weapon, ammoType); } } return num; } internal static int CountAvailableAmmo(Humanoid humanoid, ItemData weapon, string ammoType, ItemData ammoItem) { int num = CountAmmo(humanoid.GetInventory(), ammoType, ammoItem); if (TrollingFishingPlugin.FishingRodBag.Value.IsOn()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && IsFishingRod(weapon)) { num += CountFishingRodBagAmmo(val, weapon, ammoType, ammoItem); } } return num; } internal static int CountAvailableAmmoFromSource(Humanoid humanoid, ItemData weapon, string ammoType, ItemData ammoItem, FishingRodAmmoSource source) { if ((Object)(object)humanoid == (Object)null || weapon == null || string.IsNullOrWhiteSpace(ammoType) || ammoItem == null) { return 0; } switch (source) { case FishingRodAmmoSource.Inventory: return CountAmmo(humanoid.GetInventory(), ammoType, ammoItem); case FishingRodAmmoSource.FishingRodBag: if (TrollingFishingPlugin.FishingRodBag.Value.IsOn()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && IsFishingRod(weapon)) { return CountFishingRodBagAmmo(val, weapon, ammoType, ammoItem); } } break; } return 0; } internal static bool TryResolveFishingRodAmmo(Humanoid humanoid, ItemData weapon, out ItemData ammoItem) { ammoItem = null; if (!TryResolveFishingRodAmmoSelection(humanoid, weapon, out var selection)) { return false; } ammoItem = selection.AmmoItem; return true; } internal static bool TryResolveFishingRodAmmoSelection(Humanoid humanoid, ItemData weapon, out FishingRodAmmoSelection selection) { selection = default(FishingRodAmmoSelection); if ((Object)(object)humanoid == (Object)null || weapon == null || string.IsNullOrWhiteSpace(weapon.m_shared.m_ammoType)) { return false; } string ammoType = weapon.m_shared.m_ammoType; Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && TryFindEquippedInventoryAmmo(val, ammoType, out ItemData ammoItem)) { selection = new FishingRodAmmoSelection(ammoItem, FishingRodAmmoSource.Inventory); return true; } if (TryFindFishingRodAmmo(humanoid, weapon, out ItemData ammoItem2)) { selection = new FishingRodAmmoSelection(ammoItem2, FishingRodAmmoSource.FishingRodBag); return true; } Inventory inventory = humanoid.GetInventory(); ItemData ammoItem3 = humanoid.GetAmmoItem(); if (ammoItem3 != null && inventory.ContainsItem(ammoItem3) && IsMatchingAmmo(ammoItem3, ammoType)) { selection = new FishingRodAmmoSelection(ammoItem3, FishingRodAmmoSource.Inventory); return true; } ammoItem3 = inventory.GetAmmoItem(ammoType, (string)null); if (ammoItem3 == null) { return false; } selection = new FishingRodAmmoSelection(ammoItem3, FishingRodAmmoSource.Inventory); return true; } internal static bool TryFindFishingRodAmmo(Humanoid humanoid, ItemData weapon, out ItemData ammoItem) { ammoItem = null; if (!TrollingFishingPlugin.FishingRodBag.Value.IsOff()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && IsFishingRod(weapon) && !string.IsNullOrWhiteSpace(weapon.m_shared.m_ammoType) && !TryFindEquippedInventoryAmmo(val, weapon.m_shared.m_ammoType, out ItemData _)) { return TryFindFishingRodBagAmmo(val, weapon, weapon.m_shared.m_ammoType, out ammoItem); } } return false; } internal static bool HasFishingRodBagAmmo(Humanoid humanoid, ItemData weapon) { if (TrollingFishingPlugin.FishingRodBag.Value.IsOn()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && IsFishingRod(weapon) && !string.IsNullOrWhiteSpace(weapon.m_shared.m_ammoType) && !TryFindEquippedInventoryAmmo(val, weapon.m_shared.m_ammoType, out ItemData _)) { return CountFishingRodBagAmmo(val, weapon, weapon.m_shared.m_ammoType) > 0; } } return false; } internal static bool TryUseFishingRodBagAmmoForVanillaAttack(Attack attack, ref ItemData ammoItem, out bool result) { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Invalid comparison between Unknown and I4 Attack attack2 = attack; result = true; ammoItem = null; if (!TrollingFishingPlugin.FishingRodBag.Value.IsOff()) { Humanoid obj = attack2?.m_character; Player val = (Player)(object)((obj is Player) ? obj : null); if (val != null && IsFishingRod(attack2.m_weapon) && !string.IsNullOrWhiteSpace(attack2.m_weapon.m_shared.m_ammoType) && !TryFindEquippedInventoryAmmo(val, attack2.m_weapon.m_shared.m_ammoType, out ItemData _) && TryFindFishingRodBagAmmo(val, attack2.m_weapon, attack2.m_weapon.m_shared.m_ammoType, out ItemData bagAmmo)) { int width; int height; Inventory val2 = LoadFishingRodBagInventory(val, attack2.m_weapon, out width, out height); ItemData val3 = ((IEnumerable<ItemData>)val2.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => IsMatchingAmmo(item, attack2.m_weapon.m_shared.m_ammoType) && (Object)(object)item.m_dropPrefab == (Object)(object)bagAmmo.m_dropPrefab)) ?? val2.GetAmmoItem(attack2.m_weapon.m_shared.m_ammoType, (string)null); if (val3 == null) { return false; } if ((int)val3.m_shared.m_itemType == 2) { if (!((Humanoid)val).ConsumeItem(val2, val3, false)) { result = false; return true; } } else { val2.RemoveItem(val3, 1); } SaveFishingRodBagInventory(attack2.m_weapon, val2); RegisterAttackBaitReturnSource(attack2, val, attack2.m_weapon, bagAmmo); ammoItem = bagAmmo; attack2.m_ammoItem = bagAmmo; return true; } } return false; } internal static bool TryUseFishingRodBagItem(Humanoid humanoid, Inventory inventory, ItemData item) { if (!TrollingFishingPlugin.FishingRodBag.Value.IsOff()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && inventory != null && item != null && FishingRodBagStoreState.InventoryOwners.TryGetValue(inventory, out ItemData value) && IsFishingRod(value)) { TryResolveMissingDropPrefab(item); if (!string.IsNullOrWhiteSpace(value.m_shared.m_ammoType) && IsMatchingAmmo(item, value.m_shared.m_ammoType)) { if ((Object)(object)item.m_dropPrefab == (Object)null) { return false; } if (IsSelectedFishingRodBagBait(value, item)) { value.m_customData.Remove("TrollingFishing.FishingRodBag.SelectedBait"); NotifyFishingRodBagBaitSelectionChanged(val, inventory, value, saveBagInventory: true); ((Character)val).Message((MessageType)2, "$msg_removed " + item.m_shared.m_name, 0, (Sprite)null); TrollingFishingPlugin.LogDebug("[Fishing bag] unselected bait " + ((Object)item.m_dropPrefab).name + " for rod bag."); return true; } UnequipMatchingInventoryAmmo(val, value.m_shared.m_ammoType); value.m_customData["TrollingFishing.FishingRodBag.SelectedBait"] = ((Object)item.m_dropPrefab).name; NotifyFishingRodBagBaitSelectionChanged(val, inventory, value, saveBagInventory: true); ((Character)val).Message((MessageType)2, "$msg_added " + item.m_shared.m_name, 0, (Sprite)null); TrollingFishingPlugin.LogDebug("[Fishing bag] selected bait " + ((Object)item.m_dropPrefab).name + " for rod bag."); return true; } if (IsFishChumItem(item)) { return TryMoveFishChumToPlayerInventoryAndUse(val, inventory, item); } return false; } } return false; } internal static void SyncFishingRodBagBaitAfterInventoryUse(Humanoid humanoid, Inventory inventory, ItemData item) { if (!TrollingFishingPlugin.FishingRodBag.Value.IsOff()) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && inventory != null && item != null && inventory == ((Humanoid)val).GetInventory()) { TryResolveMissingDropPrefab(item); ClearMatchingFishingRodBagBaitSelections(val, item); } } } private static bool IsSelectedFishingRodBagBait(ItemData rod, ItemData item) { if (rod != null && (Object)(object)item?.m_dropPrefab != (Object)null && rod.m_customData.TryGetValue("TrollingFishing.FishingRodBag.SelectedBait", out var value)) { return string.Equals(value, ((Object)item.m_dropPrefab).name, StringComparison.OrdinalIgnoreCase); } return false; } private static bool TryFindEquippedInventoryAmmo(Player player, string ammoType, out ItemData ammoItem) { ammoItem = null; Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null || string.IsNullOrWhiteSpace(ammoType)) { return false; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_equipped && IsMatchingAmmo(allItem, ammoType)) { ammoItem = allItem; return true; } } ItemData ammoItem2 = ((Humanoid)player).GetAmmoItem(); if (ammoItem2 != null && inventory.ContainsItem(ammoItem2) && IsMatchingAmmo(ammoItem2, ammoType)) { ammoItem = ammoItem2; return true; } return false; } private static bool TryFindEquippedInventoryAmmo(Player player, ItemData sourceAmmo, out ItemData ammoItem) { ammoItem = null; Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null || sourceAmmo == null) { return false; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_equipped && IsSameAmmoPrefabOrName(allItem, sourceAmmo)) { ammoItem = allItem; return true; } } ItemData ammoItem2 = ((Humanoid)player).GetAmmoItem(); if (ammoItem2 != null && inventory.ContainsItem(ammoItem2) && IsSameAmmoPrefabOrName(ammoItem2, sourceAmmo)) { ammoItem = ammoItem2; return true; } return false; } private static void UnequipMatchingInventoryAmmo(Player player, string ammoType) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null || string.IsNullOrWhiteSpace(ammoType)) { return; } bool flag = false; foreach (ItemData item in inventory.GetAllItems().ToList()) { if (item.m_equipped && IsMatchingAmmo(item, ammoType)) { ((Humanoid)player).UnequipItem(item, true); flag = true; } } ItemData ammoItem = ((Humanoid)player).GetAmmoItem(); if (ammoItem != null && inventory.ContainsItem(ammoItem) && IsMatchingAmmo(ammoItem, ammoType)) { ((Humanoid)player).UnequipItem(ammoItem, true); flag = true; } if (flag) { inventory.Changed(); } } private static void ClearMatchingFishingRodBagBaitSelections(Player player, ItemData equippedAmmo) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null || equippedAmmo == null) { return; } bool flag = false; foreach (ItemData allItem in inventory.GetAllItems()) { if (IsFishingRod(allItem) && !string.IsNullOrWhiteSpace(allItem.m_shared.m_ammoType) && IsMatchingAmmo(equippedAmmo, allItem.m_shared.m_ammoType) && allItem.m_customData.ContainsKey("TrollingFishing.FishingRodBag.SelectedBait")) { allItem.m_customData.Remove("TrollingFishing.FishingRodBag.SelectedBait"); NotifyOpenFishingRodBagInventoriesChanged(allItem, saveBagInventories: false); flag = true; } } if (flag) { inventory.Changed(); TrollingFishingPlugin.LogDebug("[Fishing bag] cleared selected bag bait because an inventory bait was equipped."); } } private static void NotifyFishingRodBagBaitSelectionChanged(Player player, Inventory bagInventory, ItemData rod, bool saveBagInventory) { NotifyOpenFishingRodBagInventoriesChanged(rod, saveBagInventory); if (saveBagInventory && bagInventory != null) { bagInventory.Changed(); } if (player != null) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory != null) { inventory.Changed(); } } } private static void NotifyOpenFishingRodBagInventoriesChanged(ItemData rod, bool saveBagInventories) { if (rod == null) { return; } foreach (KeyValuePair<Inventory, ItemData> item in FishingRodBagStoreState.InventoryOwners.ToList()) { if (item.Value != rod) { continue; } Inventory key = item.Key; if (key != null) { if (saveBagInventories) { key.Changed(); } else { MarkFishingRodBagInventoryVisualDirty(key); } } } } private static bool IsSameAmmoPrefabOrName(ItemData item, ItemData sourceAmmo) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (item == null || sourceAmmo == null) { return false; } if (!IsAmmoItemType(item.m_shared.m_itemType) || !IsAmmoItemType(sourceAmmo.m_shared.m_itemType)) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null && (Object)(object)sourceAmmo.m_dropPrefab != (Object)null) { return string.Equals(((Object)item.m_dropPrefab).name, ((Object)sourceAmmo.m_dropPrefab).name, StringComparison.OrdinalIgnoreCase); } return string.Equals(item.m_shared.m_name, sourceAmmo.m_shared.m_name, StringComparison.OrdinalIgnoreCase); } private static bool TryMoveFishChumToPlayerInventoryAndUse(Player player, Inventory bagInventory, ItemData item) { if ((Object)(object)player == (Object)null || bagInventory == null || item == null || (Object)(object)item.m_dropPrefab == (Object)null) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return true; } ItemData val = FindMatchingInventoryItem(inventory, item, requireEquipped: true); if (!inventory.CanAddItem(item, item.m_stack)) { ((Character)player).Message((MessageType)1, Localization.instance.Localize("$inventory_full"), 0, (Sprite)null); return true; } ItemData val2 = item.Clone(); val2.m_equipped = false; if (!inventory.AddItem(val2)) { ((Character)player).Message((MessageType)1, Localization.instance.Localize("$inventory_full"), 0, (Sprite)null); return true; } bagInventory.RemoveItem(item); bagInventory.Changed(); if (val != null && inventory.ContainsItem(val)) { ((Character)player).Message((MessageType)2, "$msg_added " + val2.m_shared.m_name, 0, (Sprite)null); return true; } ItemData val3 = (ItemData)(inventory.ContainsItem(val2) ? ((object)val2) : ((object)FindMatchingInventoryItem(inventory, val2, requireEquipped: false))); if (val3 == null) { return true; } ((Humanoid)player).UseItem(inventory, val3, true); return true; } private static ItemData? FindMatchingInventoryItem(Inventory inventory, ItemData source, bool requireEquipped) { if (inventory == null || source == null) { return null; } string text = (((Object)(object)source.m_dropPrefab != (Object)null) ? StripCloneSuffix(((Object)source.m_dropPrefab).name) : null); foreach (ItemData allItem in inventory.GetAllItems()) { if ((!requireEquipped || allItem.m_equipped) && (requireEquipped || !allItem.m_equipped) && allItem.m_quality == source.m_quality && allItem.m_worldLevel == source.m_worldLevel) { if (!string.IsNullOrWhiteSpace(text) && (Object)(object)allItem.m_dropPrefab != (Object)null && string.Equals(StripCloneSuffix(((Object)allItem.m_dropPrefab).name), text, StringComparison.OrdinalIgnoreCase)) { return allItem; } if (string.Equals(allItem.m_shared.m_name, source.m_shared.m_name, StringComparison.OrdinalIgnoreCase)) { return allItem; } } } return null; } private static int CountAmmo(Inventory inventory, string ammoType) { if (inventory == null || string.IsNullOrWhiteSpace(ammoType)) { return 0; } int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (IsMatchingAmmo(allItem, ammoType)) { num += allItem.m_stack; } } return num; } private static int CountAmmo(Inventory inventory, string ammoType, ItemData targetAmmo) { if (inventory == null || string.IsNullOrWhiteSpace(ammoType) || targetAmmo == null) { return 0; } int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (IsMatchingAmmo(allItem, ammoType, targetAmmo)) { num += allItem.m_stack; } } return num; } private static bool IsMatchingAmmo(ItemData item, string ammoType) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (item == null || string.IsNullOrWhiteSpace(ammoType)) { return false; } if (!IsAmmoItemType(item.m_shared.m_itemType)) { return false; } if (!string.Equals(item.m_shared.m_ammoType, ammoType, StringComparison.OrdinalIgnoreCase)) { if ((Object)(object)item.m_dropPrefab != (Object)null) { return string.Equals(((Object)item.m_dropPrefab).name, ammoType, StringComparison.OrdinalIgnoreCase); } return false; } return true; } private static bool IsMatchingAmmo(ItemData item, string ammoType, ItemData targetAmmo) { if (!IsMatchingAmmo(item, ammoType) || targetAmmo == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null && (Object)(object)targetAmmo.m_dropPrefab != (Object)null) { return string.Equals(((Object)item.m_dropPrefab).name, ((Object)targetAmmo.m_dropPrefab).name, StringComparison.OrdinalIgnoreCase); } return string.Equals(item.m_shared.m_name, targetAmmo.m_shared.m_name, StringComparison.OrdinalIgnoreCase); } private static bool IsAmmoItemType(ItemType itemType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if ((int)itemType != 9 && (int)itemType != 23) { return (int)itemType == 2; } return true; } private static List<ItemData> ResolveInventoryAmmoRemovalOrder(Inventory inventory, string ammoType, ItemData targetAmmo) { string ammoType2 = ammoType; ItemData targetAmmo2 = targetAmmo; if (inventory == null || string.IsNullOrWhiteSpace(ammoType2) || targetAmmo2 == null) { return new List<ItemData>(); } return (from item in inventory.GetAllItems() where IsMatchingAmmo(item, ammoType2, targetAmmo2) select item).ToList(); } private static int CountFishingRodBagAmmo(Player player, ItemData rod, string ammoType) { string ammoType2 = ammoType; int width; int height; return (from item in LoadFishingRodBagInventory(player, rod, out width, out height).GetAllItems() where IsMatchingAmmo(item, ammoType2) select item).Sum((ItemData item) => item.m_stack); } private static int CountFishingRodBagAmmo(Player player, ItemData rod, string ammoType, ItemData targetAmmo) { string ammoType2 = ammoType; ItemData targetAmmo2 = targetAmmo; int width; int height; return (from item in LoadFishingRodBagInventory(player, rod, out width, out height).GetAllItems() where IsMatchingAmmo(item, ammoType2, targetAmmo2) select item).Sum((ItemData item) => item.m_stack); } private static bool TryFindFishingRodBagAmmo(Player player, ItemData rod, string ammoType, out ItemData ammoItem) { int width; int height; Inventory val = LoadFishingRodBagInventory(player, rod, out width, out height); ItemData val2 = ResolveSelectedFishingRodBagAmmo(val, rod, ammoType) ?? val.GetAmmoItem(ammoType, (string)null); if (val2 == null) { ammoItem = null; return false; } ammoItem = val2.Clone(); ammoItem.m_stack = 1; return true; } private static ItemData? ResolveSelectedFishingRodBagAmmo(Inventory inventory, ItemData rod, string ammoType) { string ammoType2 = ammoType; if (inventory == null || rod == null || !rod.m_customData.TryGetValue("TrollingFishing.FishingRodBag.SelectedBait", out var selectedPrefabName) || string.IsNullOrWhiteSpace(selectedPrefabName)) { return null; } ItemData? obj = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => (Object)(object)item?.m_dropPrefab != (Object)null && IsMatchingAmmo(item, ammoType2) && string.Equals(((Object)item.m_dropPrefab).name, selectedPrefabName, StringComparison.OrdinalIgnoreCase))); if (obj == null) { rod.m_customData.Remove("TrollingFishing.FishingRodBag.SelectedBait"); } return obj; } private static List<ItemData> ResolveFishingRodBagAmmoRemovalOrder(Inventory inventory, ItemData rod, string ammoType, ItemData targetAmmo) { string ammoType2 = ammoType; ItemData targetAmmo2 = targetAmmo; List<ItemData> list = (from item in inventory.GetAllItems() where IsMatchingAmmo(item, ammoType2, targetAmmo2) select item).ToList(); ItemData selected = ResolveSelectedFishingRodBagAmmo(inventory, rod, ammoType2); if (selected == null) { return list; } return list.OrderByDescending((ItemData item) => item == selected).ToList(); } internal static void UpdateFishingRodBagAzuProxyLifetime(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && FishingRodBagProxyState.Proxies.Count != 0 && (!ShouldUseFishingRodBagProxies() || Time.time > FishingRodBagProxyState.KeepAliveUntil)) { DestroyFishingRodBagProxies(); } } internal static void RefreshFishingRodBagProxiesForAzuContext(Humanoid user) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && ShouldUseFishingRodBagProxies()) { FishingRodBagProxyState.KeepAliveUntil = Time.time + 2f; SyncFishingRodBagProxies(val); } } internal static void ClearFishingRodBagProxiesForAzuContext() { FishingRodBagProxyState.KeepAliveUntil = -1f; DestroyFishingRodBagProxies(); } private static bool ShouldUseFishingRodBagProxies() { if (TrollingFishingPlugin.FishingRodBag.Value.IsOn() && TrollingFishingPlugin.FishingRodBagAzuCraftyBoxesCompatibility.Value.IsOn()) { return AzuCraftyBoxesCompat.IsLoaded(); } return false; } private static void SyncFishingRodBagProxies(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { DestroyFishingRodBagProxies(); return; } ItemData val = ResolveAzuCraftyBoxesFishingRod(player, inventory); foreach (ItemData item in FishingRodBagProxyState.Proxies.Keys.ToList()) { if (item != val || FishingRodBagUiState.OpenRods.Contains(item)) { RemoveFishingRodBagProxy(item); } } if (val != null && !FishingRodBagUiState.OpenRods.Contains(val)) { if (FishingRodBagProxyState.Proxies.TryGetValue(val, out FishingRodBagProxyContainer value)) { value.SetPlayer(player); } else { CreateFishingRodBagProxy(player, val); } } } private static ItemData? ResolveAzuCraftyBoxesFishingRod(Player player, Inventory playerInventory) { ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (IsFishingRod(currentWeapon) && playerInventory.ContainsItem(currentWeapon)) { return currentWeapon; } return ((IEnumerable<ItemData>)playerInventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)IsFishingRod); } private static void CreateFishingRodBagProxy(Player player, ItemData rod) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) int slots = ResolveTargetSlotCount(player, rod); ResolveGridSize(slots, out var width, out var height); GameObject val = new GameObject("TrollingFishing_FishingRodBagProxy"); val.transform.position = ((Component)player).transform.position; FishingRodBagProxyContainer fishingRodBagProxyContainer = val.AddComponent<FishingRodBagProxyContainer>(); Container container = val.AddComponent<Container>(); fishingRodBagProxyContainer.Initialize(player, rod, container, slots, width, height); FishingRodBagProxyState.Proxies[rod] = fishingRodBagProxyContainer; } private static void RemoveFishingRodBagProxy(ItemData rod) { if (rod != null && FishingRodBagProxyState.Proxies.TryGetValue(rod, out FishingRodBagProxyContainer value)) { FishingRodBagProxyState.Proxies.Remove(rod); value.CloseAndDestroy(); } } private static void RefreshFishingRodBagProxy(ItemData rod) { if (rod != null && FishingRodBagProxyState.Proxies.TryGetValue(rod, out FishingRodBagProxyContainer value)) { value.ReloadFromRod(); } } private static void DestroyFishingRodBagProxies() { foreach (ItemData item in FishingRodBagProxyState.Proxies.Keys.ToList()) { RemoveFishingRodBagProxy(item); } } internal static bool IsFishingRodBagInventory(Inventory inventory) { if (inventory != null) { return FishingRodBagStoreState.Inventories.Contains(inventory); } return false; } internal static bool CanAddToFishingRodBag(Inventory inventory, ItemData item) { if (IsFishingRodBagInventory(inventory)) { return IsAllowedFishingRodBagItem(item); } return true; } internal static bool CanAddToFishingRodBag(Inventory inventory, GameObject itemPrefab) { if (IsFishingRodBagInventory(inventory)) { return IsAllowedFishingRodBagPrefab(itemPrefab); } return true; } private static bool IsAllowedFishingRodBagItem(ItemData item) { if (item == null) { return false; } TryResolveMissingDropPrefab(item); if ((Object)(object)item.m_dropPrefab != (Object)null) { return IsAllowedFishingRodBagPrefab(item.m_dropPrefab); } return false; } private static bool IsAllowedFishingRodBagPrefab(GameObject itemPrefab) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 if ((Object)(object)itemPrefab == (Object)null) { return false; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (component != null && (int)(component.m_itemData?.m_shared?.m_itemType).GetValueOrDefault() == 21) { return true; } if (IsCompatibleFishingItemDropPrefab(itemPrefab, component)) { return true; } if (IsFishChumPrefab(itemPrefab)) { return true; } EnsureAllowedFishingItemCache(); return FishingRodBagRulesState.AllowedPrefabNames.Contains(((Object)itemPrefab).name); } private static bool IsFishChumItem(ItemData item) { if (item == null) { return false; } TryResolveMissingDropPrefab(item); if ((Object)(object)item.m_dropPrefab != (Object)null && IsFishChumPrefab(item.m_dropPrefab)) { return true; } return false; } private static bool IsFishChumPrefab(GameObject itemPrefab) { if ((Object)(object)itemPrefab == (Object)null) { return false; } return FishingRodBagRulesState.FishChumPrefabNames.Contains(StripCloneSuffix(((Object)itemPrefab).name)); } private static bool IsCompatibleFishingItemDropPrefab(GameObject itemPrefab, ItemDrop? itemDrop) { if ((Object)(object)itemPrefab == (Object)null || (Object)(object)itemDrop == (Object)null) { return false; } string text = StripCloneSuffix(((Object)itemPrefab).name); if (!((Object)(object)itemPrefab.GetComponent<Fish>() != (Object)null)) { return text.IndexOf("Starfish", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static string StripCloneSuffix(string name) { if (name.EndsWith("(Clone)", StringComparison.Ordinal)) { return name.Substring(0, name.Length - "(Clone)".Length); } return name; } private static bool TryResolveMissingDropPrefab(ItemData item) { if (item == null || (Object)(object)item.m_dropPrefab != (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return (Object)(object)item?.m_dropPrefab != (Object)null; } GameObject dropPrefab = default(GameObject); if (ObjectDB.instance.TryGetItemPrefab(item.m_shared, ref dropPrefab)) { item.m_dropPrefab = dropPrefab; return true; } return false; } private static void EnsureAllowedFishingItemCache() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance == (Object)(object)FishingRodBagRulesState.CachedScene) { return; } FishingRodBagRulesState.CachedScene = instance; FishingRodBagRulesState.AllowedPrefabNames.Clear(); AddAllowedFishingItemsFromPrefabs(instance.m_prefabs); AddAllowedFishingItemsFromPrefabs(instance.m_nonNetViewPrefabs); if (!((Object)(object)ObjectDB.instance != (Object)null)) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item != (Object)null && ((Object)item).name.IndexOf("FishingBait", StringComparison.OrdinalIgnoreCase) >= 0) { FishingRodBagRulesState.AllowedPrefabNames.Add(((Object)item).name); } } } private static void AddAllowedFishingItemsFromPrefabs(IEnumerable<GameObject> prefabs) { foreach (GameObject prefab in prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } Fish component = prefab.GetComponent<Fish>(); if ((Object)(object)component == (Object)null) { continue; } if ((Object)(object)component.m_pickupItem != (Object)null) { FishingRodBagRulesState.AllowedPrefabNames.Add(((Object)component.m_pickupItem).name); } foreach (BaitSetting bait in component.m_baits) { if ((Object)(object)bait?.m_bait != (Object)null) { FishingRodBagRulesState.AllowedPrefabNames.Add(((Object)bait.m_bait).name); } } } } internal static bool TryCatchFishToFishingRodBag(Fish fish, Character owner, out string message) { //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_012e: 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) message = ""; if (!TrollingFishingPlugin.FishingRodBag.Value.IsOff() && !((Object)(object)fish == (Object)null)) { Player val = (Player)(object)((owner is Player) ? owner : null); if (val != null) { ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (!IsFishingRod(currentWeapon) || !TryCreateFishPickupItem(fish, out ItemData fishItem)) { return false; } int width; int height; Inventory inventory = LoadFishingRodBagInventory(val, currentWeapon, out width, out height); if (!TryAddItemToFishingRodBagInventory(inventory, fishItem)) { return false; } Vector3 position = ((Component)fish).transform.position; message = "$msg_fishing_catched " + fish.GetHoverName(); if (!fish.m_extraDrops.IsEmpty()) { foreach (ItemData dropListItem in fish.m_extraDrops.GetDropListItems()) { message = message + " & " + dropListItem.m_shared.m_name; ItemData val2 = dropListItem.Clone(); val2.m_stack = dropListItem.m_stack; if (!TryAddItemToFishingRodBagInventory(inventory, val2)) { Inventory inventory2 = ((Humanoid)val).GetInventory(); if (inventory2 != null && inventory2.CanAddItem(dropListItem.m_dropPrefab, dropListItem.m_stack)) { inventory2.AddItem(dropListItem.m_dropPrefab, dropListItem.m_stack); continue; } Object.Instantiate<GameObject>(dropListItem.m_dropPrefab, position, Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f)).GetComponent<ItemDrop>().SetStack(dropListItem.m_stack); ((Character)val).Message((MessageType)1, Localization.instance.Localize("$inventory_full"), 0, (Sprite)null); } } } SaveFishingRodBagInventory(currentWeapon, inventory); DestroyCaughtFish(fish); return true; } } return false; } internal static void RegisterFishingRodBagInventory(Inventory inventory, ItemData rod) { if (inventory != null) { FishingRodBagStoreState.Inventories.Add(inventory); if (rod != null) { FishingRodBagStoreState.InventoryOwners[inventory] = rod; } } } internal static void UnregisterFishingRodBagInventory(Inventory inventory) { if (inventory != null) { FishingRodBagStoreState.Inventories.Remove(inventory); FishingRodBagStoreState.InventoryOwners.Remove(inventory); FishingRodBagStoreState.InventoryStates.Remove(inventory); } } internal static bool IsFishingRodBagContainer(Container container) { if ((Object)(object)container != (Object)null) { if (!((Object)(object)((Component)container).GetComponent<FishingRodBagContainer>() != (Object)null)) { return (Object)(object)((Component)container).GetComponent<FishingRodBagProxyContainer>() != (Object)null; } return true; } return false; } internal static bool TrySaveFishingRodBagContainer(Container container) { if ((Object)(object)container == (Object)null) { return false; } FishingRodBagContainer component = ((Component)container).GetComponent<FishingRodBagContainer>(); if ((Object)(object)component != (Object)null) { component.Save(); return true; } FishingRodBagProxyContainer component2 = ((Component)container).GetComponent<FishingRodBagProxyContainer>(); if ((Object)(object)component2 != (Object)null) { component2.Save(); return true; } return false; } internal static float GetFishingRodBagExtraWeight(Inventory inventory) { if (TrollingFishingPlugin.FishingRodBag.Value.IsOff() || TrollingFishingPlugin.FishingRodBagCountsWeight.Value.IsOff() || inventory == null || (Object)(object)Player.m_localPlayer == (Object)null || inventory != ((Humanoid)Player.m_localPlayer).GetInventory()) { return 0f; } float num = 0f; foreach (ItemData allItem in inventory.GetAllItems()) { if (IsFishingRod(allItem)) { num += GetFishingRodBagWeight(allItem); } } return num * ResolveFishingRodBagWeightMultiplier(Player.m_localPlayer); } internal static bool TryGetFishingRodBagContainerDisplayWeight(Container container, Player player, out float weight) { weight = 0f; if (!((Object)(object)container == (Object)null) && !((Object)(object)player == (Object)null) && IsFishingRodBagContainer(container)) { Inventory inventory = container.GetInventory(); if (inventory != null && FishingRodBagStoreState.InventoryOwners.TryGetValue(inventory, out ItemData value)) { weight = GetFishingRodBagWeight(value) * ResolveFishingRodBagWeightMultiplier(player); return true; } } return false; } private static float ResolveFishingRodBagWeightMultiplier(Player player) { if ((Object)(object)player == (Object)null) { return 1f; } float num = (float)Mathf.Clamp(TrollingFishingPlugin.FishingRodBagWeightAtMaxSkillPercent.Value, 0, 100) / 100f; float num2 = Mathf.Clamp01(((Character)player).GetSkillFactor((SkillType)104)); return Mathf.Lerp(1f, num, num2); } private static int ResolveTargetSlotCount(Player player, ItemData rod) { int result = NormalizeFishingRodBagSlotCount(ResolveConfiguredSlotCount(player)); rod.m_customData["TrollingFishing.FishingRodBag.Slots"] = result.ToString(CultureInfo.InvariantCulture); return result; } private static int ResolveConfiguredSlotCount(Player player) { if (!TrollingFishingPlugin.FishingRodBagScalesWithFishingSkill.Value.IsOn()) { return 32; } return ResolveSkillSlotCount(((Character)player).GetSkillLevel((SkillType)104)); } private static int ResolveSkillSlotCount(float fishingLevel) { return (Mathf.Clamp(Mathf.FloorToInt(Mathf.Max(0f, fishingLevel) / 10f), 0, 9) + 1) * 8; } private static Inventory CreateFishingRodBagInventory(ItemData rod, int width, int height) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown return new Inventory("$item_fishingrod", rod.GetIcon(), width, height); } private static void ResolveGridSize(int slots, out int width, out int height) { int num = NormalizeFishingRodBagSlotCount(slots); if (num <= 16) { if (num <= 8) { width = 4; height = 2; } else { width = 4; height = 4; } } else if (num <= 24) { width = 6; height = 4; } else { width = 8; height = num / 8; } } private static int NormalizeFishingRodBagSlotCount(int slots) { return Mathf.CeilToInt((float)Mathf.Clamp(slots, 8, 80) / 8f) * 8; } private static bool TryAddItemToFishingRodBag(Player player, ItemData rod, ItemData item) { int width; int height; Inventory inventory = LoadFishingRodBagInventory(player, rod, out width, out height); if (!TryAddItemToFishingRodBagInventory(inventory, item)) { return false; } SaveFishingRodBagInventory(rod, inventory); return true; } private static bool TryAddItemToFishingRodBagInventory(Inventory inventory, ItemData item) { if (inventory == null || !IsAllowedFishingRodBagItem(item)) { return false; } ItemData val = item.Clone(); if (inventory.CanAddItem(val, -1)) { return inventory.AddItem(val); } return false; } private static Inventory LoadFishingRodBagInventory(Player player, ItemData rod, out int width, out int height) { int num = ResolveTargetSlotCount(player, rod); ResolveGridSize(num, out width, out height); Inventory val = CreateFishingRodBagInventory(rod, width, height); if (rod.m_customData.TryGetValue("TrollingFishing.FishingRodBag.Data", out var value) && !string.IsNullOrWhiteSpace(value)) { LoadFishingRodBagVisibleInventory(rod, val, value, num); } else { SetFishingRodBagInventoryState(val, new FishingRodBagInventoryState(new List<ItemData>(), num)); } return val; } private static void SaveFishingRodBagInventory(ItemData rod, Inventory inventory, bool refreshProxy = true) { List<ItemData> allItems = CollectFishingRodBagStoredItems(inventory); SaveFishingRodBagStoredItems(rod, allItems); InvalidateFishingRodBagWeight(rod); if (refreshProxy) { RefreshFishingRodBagProxy(rod); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { Inventory inventory2 = ((Humanoid)localPlayer).GetInventory(); if (inventory2 != null) { inventory2.Changed(); } } } private static float GetFishingRodBagWeight(ItemData rod) { if (rod == null) { return 0f; } if (!rod.m_customData.TryGetValue("TrollingFishing.FishingRodBag.Data", out var value) || string.IsNullOrWhiteSpace(value)) { FishingRodBagStoreState.WeightCache.Remove(rod); return 0f; } if (FishingRodBagStoreState.WeightCache.TryGetValue(rod, out BagWeightCacheEntry value2) && string.Equals(value2.RawData, value, StringComparison.Ordinal)) { return value2.Weight; } if (!TryLoadFishingRodBagInventoryForReadOnly(rod, value, out Inventory inventory)) { FishingRodBagStoreState.WeightCache.Remove(rod); return 0f; } float num = inventory.GetAllItems().Sum((ItemData item) => item.GetWeight(-1)); FishingRodBagStoreState.WeightCache[rod] = new BagWeightCacheEntry(value, num); return num; } private static bool TryLoadFishingRodBagInventoryForReadOnly(ItemData rod, string rawData, out Inventory inventory) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown ResolveGridSize(80, out var width, out var height); inventory = CreateFishingRodBagInventory(rod, width, height); try { inventory.Load(new ZPackage(rawData)); return true; } catch (Exception ex) { TrollingFishingPlugin.ModLogger.LogWarning((object)("Could not read FishingRod bag weight: " + ex.GetBaseException().Message)); return false; } } private static void InvalidateFishingRodBagWeight(ItemData rod) { if (rod != null) { FishingRodBagStoreState.WeightCache.Remove(rod); } } private static void LoadFishingRodBagVisibleInventory(ItemData rod, Inventory visibleInventory, string rawData, int visibleSlots) { if (!TryLoadFishingRodBagInventoryForReadOnly(rod, rawData, out Inventory inventory)) { SetFishingRodBagInventoryState(visibleInventory, new FishingRodBagInventoryState(new List<ItemData>(), visibleSlots)); return; } List<ItemData> overflowItems = MaterializeFishingRodBagVisibleItems(inventory.GetAllItems(), visibleInventory, visibleSlots); SetFishingRodBagInventoryState(visibleInventory, new FishingRodBagInventoryState(overflowItems, visibleSlots)); visibleInventory.Changed(); } private static List<ItemData> MaterializeFishingRodBagVisibleItems(IEnumerable<ItemData> sourceItems, Inventory visibleInventory, int visibleSlots) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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) List<ItemData> list = new List<ItemData>(); HashSet<Vector2i> hashSet = new HashSet<Vector2i>(); List<ItemData> list2 = new List<ItemData>(); foreach (ItemData item in from item in sourceItems orderby item.m_gridPos.y, item.m_gridPos.x select item) { ItemData val = CloneFishingRodBagItem(item); if (IsGridPositionInInventory(val.m_gridPos, visibleInventory) && hashSet.Add(val.m_gridPos) && visibleInventory.m_inventory.Count < visibleSlots) { visibleInventory.m_inventory.Add(val); } else { list2.Add(val); } } foreach (ItemData item2 in list2) { if (visibleInventory.m_inventory.Count < visibleSlots && TryFindNextFreeFishingRodBagSlot(visibleInventory, hashSet, out var slot)) { item2.m_gridPos = slot; hashSet.Add(slot); visibleInventory.m_inventory.Add(item2); } else { list.Add(item2); } } return list; } private static List<ItemData> CollectFishingRodBagStoredItems(Inventory inventory) { List<ItemData> list = (from item in inventory.GetAllItems() orderby item.m_gridPos.y, item.m_gridPos.x select item).Select(CloneFishingRodBagItem).ToList(); if (FishingRodBagStoreState.InventoryStates.TryGetValue(inventory, out FishingRodBagInventoryState value)) { list.AddRange(value.OverflowItems.Select(CloneFishingRodBagItem)); } return list; } private static void SaveFishingRodBagStoredItems(ItemData rod, List<ItemData> allItems) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) ResolveGridSize(80, out var width, out var height); Inventory val = CreateFishingRodBagInventory(rod, width, height); HashSet<Vector2i> hashSet = new HashSet<Vector2i>(); foreach (ItemData allItem in allItems) { ItemData val2 = CloneFishingRodBagItem(allItem); if (!IsGridPositionInInventory(val2.m_gridPos, val) || !hashSet.Add(val2.m_gridPos)) { if (!TryFindNextFreeFishingRodBagSlot(val, hashSet, out var slot)) { break; } val2.m_gridPos = slot; hashSet.Add(slot); } val.m_inventory.Add(val2); } ZPackage val3 = new ZPackage(); val.Save(val3); rod.m_customData["TrollingFishing.FishingRodBag.Data"] = val3.GetBase64(); } private static void SetFishingRodBagInventoryState(Inventory inventory, FishingRodBagInventoryState state) { FishingRodBagStoreState.InventoryStates.Remove(inventory); FishingRodBagStoreState.InventoryStates.Add(inventory, state); } private static ItemData CloneFishingRodBagItem(ItemData item) { ItemData obj = item.Clone(); TryResolveMissingDropPrefab(obj); return obj; } private static bool IsGridPositionInInventory(Vector2i position, Inventory inventory) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (position.x >= 0 && position.y >= 0 && position.x < inventory.GetWidth()) { return position.y < inventory.GetHeight(); } return false; } private static bool TryFindNextFreeFishingRodBagSlot(Inventory inventory, HashSet<Vector2i> occupied, out Vector2i slot) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) Vector2i val = default(Vector2i); for (int i = 0; i < inventory.GetHeight(); i++) { for (int j = 0; j < inventory.GetWidth(); j++) { ((Vector2i)(ref val))..ctor(j, i); if (!occupied.Contains(val)) { slot = val; return true; } } } slot = new Vector2i(-1, -1); return false; } private static bool TryCreateFishPickupItem(Fish fish, out ItemData fishItem) { ItemDrop component = ((Component)fish).GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { fishItem = component.m_itemData.Clone(); if ((Object)(object)fishItem.m_dropPrefab == (Object)null) { fishItem.m_dropPrefab = ((Component)component).gameObject; } return true; } fishItem = null; if ((Object)(object)fish.m_pickupItem == (Object)null) { return false; } ItemDrop component2 = fish.m_pickupItem.GetComponent<ItemDrop>(); if ((Object)(object)component2 == (Object)null) { return false; } fishItem = component2.m_itemData.Clone(); fishItem.m_dropPrefab = fish.m_pickupItem; fishItem.m_stack = Mathf.Clamp(fish.m_pickupItemStackSize, 1, fishItem.m_shared.m_maxStackSize); fishItem.m_worldLevel = (byte)Game.m_worldLevel; return true; } private static void DestroyCaughtFish(Fish fish) { ZNetView component = ((Component)fish).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.Destroy(); } else { Object.Destroy((Object)(object)((Component)fish).gameObject); } } internal static void UpdateFishingRodBagSelectedBaitVisual(InventoryGrid grid, Inventory inventory) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)grid == (Object)null || inventory == null || !FishingRodBagStoreState.InventoryOwners.TryGetValue(inventory, out ItemData value) || !(InventoryGridElementsField?.GetValue(grid) is IEnumerable enumerable)) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if (value.m_customData.TryGetValue("TrollingFishing.FishingRodBag.SelectedBait", out var value2) && !string.IsNullOrWhiteSpace(value2)) { hashSet.Add(value2); } foreach (object item in enumerable) { Type type = item.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "m_pos"); FieldInfo fieldInfo2 = AccessTools.Field(type, "m_equiped"); if (!(fieldInfo?.GetValue(item) is Vector2i val)) { continue; } object? obj = fieldInfo2?.GetValue(item); Image val2 = (Image)((obj is Image) ? obj : null); if (val2 != null) { ((Behaviour)val2).enabled = false; ItemData itemAt = inventory.GetItemAt(val.x, val.y); if (itemAt != null) { TryResolveMissingDropPrefab(itemAt); } object obj2; if (itemAt == null) { obj2 = null; } else { GameObject dropPrefab = itemAt.m_dropPrefab; obj2 = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } string text = (string)obj2; if (!string.IsNullOrWhiteSpace(text)) { ((Behaviour)val2).enabled = hashSet.Contains(text); } } } } private static void MarkFishingRodBagInventoryVisualDirty(Inventory inventory) { if (inventory != null && !((Object)(object)InventoryGui.instance == (Object)null) && !((Object)(object)InventoryGui.instance.m_containerGrid == (Object)null)) { InventoryGui.instance.m_containerGrid.UpdateInventory(inventory, Player.m_localPlayer, (ItemData)null); } } internal static void DestroyExistingFishingFloats(Character owner, FishingFloat? except = null) { if ((Object)(object)owner == (Object)null) { return; } MultiLineFishingCastState.FloatBuffer.Clear(); foreach (FishingFloat allInstance in FishingFloat.GetAllInstances()) { if ((Object)(object)allInstance != (Object)null && (Object)(object)allInstance != (Object)(object)except && (Object)(object)allInstance.GetOwner() == (Object)(object)owner) { MultiLineFishingCastState.FloatBuffer.Add(allInstance); } } foreach (FishingFloat item in MultiLineFishingCastState.FloatBuffer) { if (!((Object)(object)item == (Object)null)) { ReturnFishingFloatBaitBeforeDestroy(item); GameObject gameObject = ((Component)item).gameObject; if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(gameObject); } else { Object.Destroy((Object)(object)gameObject); } } } MultiLineFishingCastState.FloatBuffer.Clear(); } internal static void TryOpenFishingRodBagFromUseInput(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && !TrollingFishingPlugin.FishingRodBag.Value.IsOff() && !((Object)(object)InventoryGui.instance == (Object)null)) { TryCloseFishingRodBagFromInput(); } } internal static bool TryHandleInventoryGuiUseInput(InventoryGui inventoryGui) { //IL_0050: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)inventoryGui == (Object)null || TrollingFishingPlugin.FishingRodBag.Value.IsOff()) { return false; } if (TryCloseFishingRodBagFromInput()) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)inventoryGui.m_currentContainer != (Object)null || !ZInput.GetButtonDown("Use")) { return false; } Vector2 val = Vector2.op_Implicit(Input.mousePosition); ItemData item = inventoryGui.m_playerGrid.GetItem(new Vector2i(Mathf.RoundToInt(val.x), Mathf.RoundToInt(val.y))); if (!IsFishingRod(item)) { return false; } OpenFishingRodBag(localPlayer, item); return true; } internal static void UpdateInventoryWeightDisplay(InventoryGui inventoryGui, Player player) { if ((Object)(object)inventoryGui == (Object)null || (Object)(object)player == (Object)null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory != null) { int num = Mathf.CeilToInt(inventory.m_totalWeight + GetFishingRodBagExtraWeight(inventory)); int num2 = Mathf.CeilToInt(player.GetMaxCarryWeight()); if (num > num2 && Mathf.Sin(Time.time * 10f) > 0f) { inventoryGui.m_weight.text = $"<color=red>{num}</color>/{num2}"; } else { inventoryGui.m_weight.text = $"{num}/{num2}"; } } } internal static void UpdateFishingRodBagContainerWeightDisplay(InventoryGui inventoryGui, Player player) { if (!((Object)(object)inventoryGui == (Object)null) && !((Object)(object)player == (Object)null) && !((Object)(object)inventoryGui.m_containerWeight == (Object)null) && TryGetFishingRodBagContainerDisplayWeight(inventoryGui.m_currentContainer, player, out var weight)) { inventoryGui.m_containerWeight.text = Mathf.CeilToInt(weight).ToString(CultureInfo.InvariantCulture); } } internal static void AppendFishingRodTooltipHints(ItemData item, ref string tooltip) { if (item != null && IsFishingRod(item)) { List<string> list = new List<string>(); if (TrollingFishingPlugin.FishingRodBag != null && TrollingFishingPlugin.FishingRodBag.Value.IsOn()) { list.Add(FishingLocalization.Localize("$tf_fishingrod_bag_open_hint")); } if (TrollingFishingPlugin.FishingRodMultiLine != null && TrollingFishingPlugin.FishingRodMultiLine.Value.IsOn()) { list.Add(FishingLocalization.Localize("$tf_fishingrod_multi_line_hint")); } if (list.Count > 0) { tooltip = tooltip + "\n\n<color=orange>" + string.Join("\n", list) + "</color>"; } } } private static void OpenFishingRodBag(Player player, ItemData rod) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) FishingRodBagUiState.OpenRods.Add(rod); RemoveFishingRodBagProxy(rod); int slots = ResolveTargetSlotCount(player, rod); ResolveGridSize(slots, out var width, out var height); GameObject val = new GameObject("TrollingFishing_FishingRodBag"); val.transform.position = ((Component)player).transform.position; FishingRodBagContainer fishingRodBagContainer = val.AddComponent<FishingRodBagContainer>(); Container val2 = val.AddComponent<Container>(); fishingRodBagContainer.Initialize(player, rod, val2, slots, width, height); InventoryGui.instance.Show(val2, 1); ZInput.ResetButtonStatus("Use"); } private static bool TryCloseFishingRodBagFromInput() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || !IsFishingRodBagContainer(instance.m_currentContainer)) { return false; } if (ZInput.GetButtonDown("Use")) { ZInput.ResetButtonStatus("Use"); CloseFishingRodBagContainerOnly(instance); return true; } if (!IsFishingRodBagFullCloseInput()) { return false; } ResetFishingRodBagFullCloseInput(); instance.Hide(); return true; } private static void CloseFishingRodBagContainerOnly(InventoryGui inventoryGui) { if (InventoryGuiCloseContainerMethod == null) { TrollingFishingPlugin.ModLogger.LogWarning((object)"Could not close the fishing bag without closing the inventory because InventoryGui.CloseContainer was not found."); } else { InventoryGuiCloseContainerMethod.Invoke(inventoryGui, Array.Empty<object>()); } } private static bool IsFishingRodBagFullCloseInput() { if (!ZInput.GetButtonDown("Inventory") && !ZInput.GetButtonDown("JoyButtonB") && !ZInput.GetButtonDown("JoyButtonY")) { return ZInput.GetKeyDown((KeyCode)27, true); } return true; } private static void ResetFishingRodBagFullCloseInput() { ZInput.ResetButtonStatus("Inventory"); ZInput.ResetButtonStatus("JoyButtonB"); ZInput.ResetButtonStatus("JoyButtonY"); } internal static FishingFloat? FindFloatWithSkillChance(Fish fish) { //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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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)fish == (Object)null) { return null; } Vector3 position = ((Component)fish).transform.position; float num = Mathf.Clamp01(fish.m_baseHookChance); float targetChance = Mathf.Max(num, Mathf.Clamp(TrollingFishingPlugin.FishingOverrideBiteChanceBonusFactor.Value, 0.1f, 1f)); foreach (FishingFloat allInstance in FishingFloat.GetAllInstances()) { if ((Object)(object)allInstance == (Object)null || !allInstance.IsInWater()) { continue; } float num2 = Mathf.Max(0f, allInstance.m_range); Vector3 val = position - ((Component)allInstance).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > num2 * num2) && !((Object)(object)allInstance.GetCatch() != (Object)null)) { float num3 = ResolveBiteChance(num, targetChance, GetFishingFloatOwnerSkillFactor(allInstance)); if (Random.value < num3) { return allInstance; } } } return null; } internal static ExtraDropChanceState ApplyExtraDropChance(Fish fish, Character character) { if (!((Object)(object)fish == (Object)null)) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null && fish.m_extraDrops != null && !fish.m_extraDrops.IsEmpty()) { DropTable extraDrops = fish.m_extraDrops; float dropChance = extraDrops.m_dropChance; extraDrops.m_dropChance = ResolveExtraDropChance(dropChance, val); return new ExtraDropChanceState(extraDrops, dropChance); } } return default(ExtraDropChanceState); } internal static void RestoreExtraDropChance(ExtraDropChanceState state) { if (state.DropTable != null) { state.DropTable.m_dropChance = state.OriginalDropChance; } } private static float ResolveBiteChance(float baseChance, float targetChance, float skillFactor) { if (skillFactor <= 0f) { return baseChance; } return Mathf.Clamp01(Mathf.Lerp(baseChance, targetChance, Mathf.Clamp01(skillFactor))); } private static float GetFishingFloatOwnerSkillFactor(FishingFloat fishingFloat) { int frameCount = Time.frameCount; if (_fishingFloatOwnerSkillFactorCacheFrame != frameCount) { _fishingFloatOwnerSkillFactorCacheFrame = frameCount; FishingFloatOwnerSkillFactorCache.Clear(); } if (FishingFloatOwnerSkillFactorCache.TryGetValue(fishingFloat, out var value)) { return value; } Character owner = fishingFloat.GetOwner(); Player val = (Player)(object)((owner is Player) ? owner : null); value = ((val != null) ? Mathf.Clamp01(((Character)val).GetSkillFactor((SkillType)104)) : 0f); FishingFloatOwnerSkillFactorCache[fishingFloat] = value; return value; } private static float ResolveExtraDropChance(float baseChance, Player? player) { float num = Mathf.Clamp01(baseChance); if ((Object)(object)player == (Object)null) { return num; } float num2 = Mathf.Clamp01(((Character)player).GetSkillFactor((SkillType)104)); float num3 = Mathf.Clamp(TrollingFishingPlugin.FishingOverrideExtraDropChanceBonusFactor.Value, 0f, 2f); return Mathf.Clamp01(num * (1f + num3 * num2)); } internal static bool IsFishingRod(ItemData? item) { if ((Object)(object)item?.m_dropPrefab != (Object)null) { return string.Equals(((Object)item.m_dropPrefab).name, "FishingRod", StringComparison.OrdinalIgnoreCase); } return false; } private static bool TryCreateItemFromPrefabName(string prefabName, out ItemData item) { item = null; if (string.IsNullOrWhiteSpace(prefabName) || (Object)(object)ZNetScene.instance == (Object)null) { return false; } GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { return false; } item = val.m_itemData.Clone(); item.m_stack = 1; item.m_dropPrefab = prefab; return true; } internal static IDisposable BeginMultiLineFishingSetup() { MultiLineFishingCastState.SetupDepth++; MultiLineFishingCastState.SetupContexts.Add(MultiLineFishingSetupContext.Empty); return new MultiLineFishingSetupScope(); } private static IDisposable BeginMultiLineFishingSetup(MultiLineFishingFloatMarker sourceMarker) { return BeginMultiLineFishingSetup(sourceMarker, consumeTrackedBaitOnSetup: false); } private static IDisposable BeginMultiLineFishingSetup(MultiLineFishingFloatMarker sourceMarker, bool consumeTrackedBaitOnSetup) { MultiLineFishingCastState.SetupDepth++; MultiLineFishingCastState.SetupContexts.Add(new MultiLineFishingSetupContext(sourceMarker.Owner, sourceMarker.Rod, sourceMarker.LineIndex, sourceMarker.PrimaryEquivalentLineIndex, sourceMarker.ReservedBait, sourceMarker.BaitReturnSource, consumeTrackedBaitOnSetup)); return new MultiLineFishingSetupScope(); } internal static bool IsMultiLineFishingSetupActive() { return MultiLineFishingCastState.SetupDepth > 0; } internal static void MarkMultiLineFishingFloat(FishingFloat fishingFloat, Character owner) { if (!((Object)(object)fishingFloat == (Object)null) && !((Object)(object)owner == (Object)null)) { MultiLineFishingSetupContext multiLineFishingSetupContext = CurrentMultiLineSetupContext(); Character owner2 = multiLineFishingSetupContext.Owner ?? owner; MarkMultiLineFishingObject(((Component)fishingFloat).gameObject, owner2, multiLineFishingSetupContext.LineIndex, multiLineFishingSetupContext.PrimaryEquivalentLineIndex, multiLineFishingSetupContext.ReservedBait, multiLineFishingSetupContext.Rod, multiLineFishingSetupContext.BaitReturnSource); } } internal static void MarkMultiLineFishingObject(GameObject projectileObject, Character owner, int lineIndex = 0, int primaryEquivalentLineIndex = 0, MultiLineBaitReservation reservedBait = default(MultiLineBaitReservation), ItemData? rod = null, MultiLineBaitReservation baitReturnSource = default(MultiLineBaitReservation)) { if (!((Object)(object)projectileObject == (Object)null) && !((Object)(object)owner == (Object)null)) { MultiLineFishingFloatMarker multiLineFishingFloatMarker = projectileObject.GetComponent<MultiLineFishingFloatMarker>() ?? projectileObject.AddComponent<MultiLineFishingFloatMarker>(); multiLineFishingFloatMarker.Initialize(owner, rod, Time.time + 8f, lineIndex, primaryEquivalentLineIndex, reservedBait, baitReturnSource); MultiLineBaitReservation baitReturnSource2 = (reservedBait.IsValid ? reservedBait : baitReturnSource); if (baitReturnSource2.IsValid) { MarkFishingBaitReturnSource(projectileObject, baitReturnSource2, CurrentMultiLineSetupContext().ConsumeTrackedBaitOnSetup); } TrollingFishingPlugin.LogDebug($"[Fishing multiLine] marked float object={((Object)projectileObject).name} line={multiLineFishingFloatMarker.LineIndex} primaryLine={multiLineFishingFloatMarker.PrimaryEquivalentLineIndex} extra={multiLineFishingFloatMarker.IsAdditionalLine} reservedBait={multiLineFishingFloatMarker.ReservedBait.PrefabName} hasFishingFloat={(Object)(object)projectileObject.GetComponent<FishingFloat>() != (Object)null} hasProjectile={(Object)(object)projectileObject.GetComponent<Projectile>() != (Object)null}."); } } private static MultiLineFishingSetupContext CurrentMultiLineSetupContext() { if (MultiLineFishingCastState.SetupContexts.Count <= 0) { return MultiLineFishingSetupContext.Empty; } return MultiLineFishingCastState.SetupContexts[MultiLineFishingCastState.SetupContexts.Count - 1]; } internal static bool TrySuppressMultiLineFishingFloatInitialUpdate(FishingFloat fishingFloat) { if ((Object)(object)fishingFloat == (Object)null) { return false; } MultiLineFishingFloatMarker component = ((Component)fishingFloat).GetComponent<MultiLineFishingFloatMarker>(); if ((Object)(object)component == (Object)null) { return false; } if (component.ShouldSkipAttackCancellation()) { return true; } return false; } internal static bool TrySuppressMultiLineFishingFindFloat(out FishingFloat result) { result = null; return IsMultiLineFishingSetupActive(); } internal static IDisposable? BeginAdditionalMultiLineFishingFloatUpdate(FishingFloat fishingFloat) { if ((Object)(object)fishingFloat == (Object)null) { return null; } MultiLineFishingFloatMarker component = ((Component)fishingFloat).GetComponent<MultiLineFishingFloatMarker>(); if ((Object)(object)component == (Object)null || !component.IsAdditionalLine) { return null; } Character val = component.Owner ?? fishingFloat.GetOwner(); if ((Object)(object)val == (Object)null) { return null; } MultiLineFishingCastState.UpdateContexts.Add(new MultiLineFishingUpdateContext(val, Mathf.Max(0f, TrollingFishingPlugin.FishingRodMultiLineExtraPullStaminaFactor.Value), Mathf.Max(0f, TrollingFishingPlugin.FishingRodMultiLineSkillRaiseFactor.Value))); return new MultiLineFishingUpdateScope(); } internal static void AdjustMultiLineFishingStaminaUse(Character character, ref float stamina) { if (!(stamina <= 0f) && TryGetCurrentMultiLineFishingUpdateContext(character, out var context)) { stamina *= context.StaminaFactor; } } internal static void AdjustMultiLineFishingSkillRaise(Character character, SkillType skillType, ref float factor) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if (!(factor <= 0f) && (int)skillType == 104 && TryGetCurrentMultiLineFishingUpdateContext(character, out var context)) { factor *= context.SkillRaiseFactor; } } private static bool TryGetCurrentMultiLineFishingUpdateContext(Character character, out MultiLineFishingUpdateContext context) { if ((Object)(object)character != (Object)null) { for (int num = MultiLineFishingCastState.UpdateContexts.Count - 1; num >= 0; num--) { MultiLineFishingUpdateContext multiLineFishingUpdateContext = MultiLineFishingCastState.UpdateContexts[num]; if (multiLineFishingUpdateContext.Owner == character) { context = multiLineFishingUpdateContext; return true; } } } context = default(MultiLineFishingUpdateContext); return false; } internal static bool TrySettleMultiLineFishingProjectileOnWater(Projectile projectile, Vector3 hitPoint, bool water) { //IL_006f: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) if (!water || (Object)(object)projectile == (Object)null) { return false; } MultiLineFishingFloatMarker component = ((Component)projectile).GetComponent<MultiLineFishingFloatMarker>(); FishingFloat component2 = ((Component)projectile).GetComponent<FishingFloat>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { if ((Object)(object)component2 != (Object)null) { TrollingFishingPlugin.LogDebug($"[Fishing multiLine] water hit not intercepted object={((Object)((Component)projectile).gameObject).name} hasMarker={(Object)(object)component != (Object)null}."); } return false; } TrollingFishingPlugin.LogDebug($"[Fishing multiLine] water hit intercepted object={((Object)((Component)projectile).gameObject).name} point={hitPoint}."); ((Component)projectile).transform.position = hitPoint; ProjectileAccess.SetVelocity(projectile, Vector3.zero); ProjectileAccess.SetDidHit(projectile, didHit: true); projectile.m_ttl = 0f; projectile.m_hitWaterEffects.Create(hitPoint, Quaternion.identity, (Transform)null, 1f, -1); Rigidbody component3 = ((Component)projectile).GetComponent<Rigidbody>(); if ((Object)(object)component3 != (Object)null) { component3.linearVelocity = Vector3.zero; component3.angularVelocity = Vector3.zero; } ((Behaviour)projectile).enabled = false; return true; } internal static bool TryBeginFishingProjectileHit(Projectile projectile, Collider collider, bool water, out IDisposable? scope) { scope = null; if ((Object)(object)projectile == (Object)null || (Object)(object)((Component)projectile).GetComponent<FishingFloat>() != (Object)null) { return false; } MultiLineFishingFloatMarker component = ((Component)projectile).GetComponent<MultiLineFishingFloatMarker>(); if ((Object)(object)component != (Object)null) { bool flag = component.IsAdditionalLine && !water && ProjectileAccess.WillDestroyAfterHit(projectile, collider); scope = BeginMultiLineFishingSetup(component, flag); TrollingFishingPlugin.LogDebug($"[Fishing multiLine] hit spawn scope opened projectile={((Object)((Component)projectile).gameObject).name} water={water} consumeTrackedBaitOnSetup={flag}."); return true; } FishingBaitReturnTracker component2 = ((Component)projectile).GetComponent<FishingBaitReturnTracker>(); if ((Object)(object)component2 == (Object)null || !component2.Source.IsValid || component2.IsSettled) { return false; } scope = BeginBaitReturnSourceSetup(component2.Source); TrollingFishingPlugin.LogDebug($"[Fishing bait] hit spawn source scope opened projectile={((Object)((Component)projectile).gameObject).name} prefab={component2.Source.PrefabName} fromRodBag={component2.Source.FromRodBag}."); return true; } internal static void ReturnFishingFloatBaitBeforeDestroy(FishingFloat fishingFloat) { if (!((Object)(object)fishingFloat == (Object)null) && !IsFishingFloatBaitConsumed(fishingFloat) && !TryReturnBaitToOriginalSource(fishingFloat)) { fishingFloat.ReturnBait(); } } internal static void LogMultiLineFishingFloatSetup(FishingFloat fishingFloat, Character owner, string phase) { if (!((Object)(object)fishingFloat == (Object)null)) { TrollingFishingPlugin.LogDebug(string.Format("[Fishing multiLine] setup {0} object={1} setupActive={2} owner={3} hasMarker={4}.", phase, ((Object)((Component)fishingFloat).gameObject).name, IsMultiLineFishingSetupActive(), ((Object)(object)owner != (Object)null) ? ((Object)owner).name : "null", (Object)(object)((Component)fishingFloat).GetComponent<MultiLineFishingFloatMarker>() != (Object)null)); } } internal static void LogMultiLineFishingFloatDestroyed(FishingFloat fishingFloat) { if (!((Object)(object)fishingFloat == (Object)null)) { MultiLineFishingFloatMarker component = ((Component)fishingFloat).GetComponent<MultiLineFishingFloatMarker>(); if (!((Object)(object)component == (Object)null)) { Character owner = component.Owner; TrollingFishingPlugin.LogDebug(string.Format("[Fishing multiLine] float destroyed object={0} owner={1} ownerInAttack={2} ownerDrawing={3} inWater={4}.", ((Object)((Component)fishingFloat).gameObject).name, ((Object)(object)owner != (Object)null) ? ((Object)owner).name : "null", (Object)(object)owner != (Object)null && owner.InAttack(), (Object)(object)owner != (Object)null && owner.IsDrawingBow(), fishingFloat.IsInWater())); } } } internal static void RegisterAttackBaitReturnSource(Attack attack, Player player, ItemData rod, ItemData bait) { if (attack != null && !((Object)(object)player == (Object)null) && !((Object)(object)bait?.m_dropPrefab == (Object)null)) { MultiLineBaitReservation source = new MultiLineBaitReservation(((Object)bait.m_dropPrefab).name, fromRodBag: true, rod); BaitSourceTrackerState.AttackSources.Remove(attack); BaitSourceTrackerState.AttackSources.Add(attack, new AttackBaitReturnSourceState(source)); TrollingFishingPlugin.LogDebug("[Fishing bait] registered attack bait return source prefab=" + ((Object)bait.m_dropPrefab).name + " fromRodBag=true."); } } internal static MultiLineBaitReservation ResolveAttackBaitReturnSource(Attack attack, ItemData? ammo) { if (!TryGetAttackBaitReturnSource(attack, ammo, out var source)) { return default(MultiLineBaitReservation); } BaitSourceTrackerState.AttackSources.Remove(attack); return source; } internal static IDisposable? BeginAttackBaitReturnSourceSetup(Attack attack) { if (attack == null || !TryGetAttackBaitReturnSource(attack, attack.m_lastUsedAmmo ?? attack.m_ammoItem, out var source)) { return null; } return BeginBaitReturnSourceSetup(source, attack); } private static IDisposable BeginBaitReturnSourceSetup(MultiLineBaitReservation source, Attack? attack = null) { BaitSourceTrackerState.SetupContexts.Add(source); return new BaitReturnSetupScope(attack); } internal static void MarkFishingFloatBaitReturnSource(FishingFloat fishingFloat, Character owner, ItemData? ammo) { MultiLineBaitReservation multiLineBaitReservation = CurrentBaitReturnSetupContext(); if (!((Object)(object)fishingFloat == (Object)null) && multiLineBaitReservation.IsValid && IsMatchingBaitReturnAmmo(multiLineBaitReservation, ammo)) { MarkFishingBaitReturnSource(((Component)fishingFloat).gameObject, multiLineBaitReservation); TrollingFishingPlugin.LogDebug($"[Fishing bait] marked bait return source prefab={multiLineBaitReservation.PrefabName} fromRodBag={multiLineBaitReservation.FromRodBag}."); } } internal static void MarkProjectileBaitReturnSource(Projectile projectile, ItemData? ammo) { MultiLineBaitReservation multiLineBaitReservation = CurrentBaitReturnSetupContext(); if (!((Object)(object)projectile == (Object)null) && multiLineBaitReservation.IsValid && IsMatchingBaitReturnAmmo(multiLineBaitReservation, ammo)) { MarkFishingBaitReturnSource(((Component)projectile).gameObject, multiLineBaitReservation); TrollingFishingPlugin.LogDebug($"[Fishing bait] marked projectile bait return source prefab={multiLineBaitReservation.PrefabName} fromRodBag={multiLineBaitReservation.FromRodBag}."); } } private static void MarkFishingBaitReturnSource(GameObject sourceObject, MultiLineBaitReservation baitReturnSource, bool settled = false) { if (!((Object)(object)sourceObject == (Object)null) && baitReturnSource.IsValid) { (sourceObject.GetComponent<FishingBaitReturnTracker>() ?? sourceObject.AddComponent<FishingBaitReturnTracker>()).Initialize(baitReturnSource, settled); } } private static bool TryGetAttackBaitReturnSource(Attack attack, ItemData? ammo, out MultiLineBaitReservation source) { source = default(MultiLineBaitReservation); if (attack == null || !BaitSourceTrackerState.AttackSources.TryGetValue(attack, out AttackBaitReturnSourceState value)) { return false; } if (!IsMatchingBaitReturnAmmo(value.Source, ammo)) { return false; } source = value.Source; return true; } private static bool IsMatchingBaitReturnAmmo(MultiLineBaitReservation source, ItemData? ammo) { if (source.IsValid && (Object)(object)ammo?.m_dropPrefab != (Object)null) { return string.Equals(source.PrefabName, ((Object)ammo.m_dropPrefab).name, StringComparison.OrdinalIgnoreCase); } return false; } private static MultiLineBaitReservation CurrentBaitReturnSetupContext() { if (BaitSourceTrackerState.SetupContexts.Count <= 0) { return default(MultiLineBaitReservation); } return BaitSourceTrackerState.SetupContexts[BaitSourceTrackerState.SetupContexts.Count - 1]; } internal static bool TryReturnBaitToOriginalSource(FishingFloat fishingFloat) { if ((Object)(object)fishingFloat == (Object)null) { return false; } if (TryReturnTrackedBaitToOriginalSource(((Component)fishingFloat).gameObject, fishingFloat)) { return true; } MultiLineFishingFloatMarker component = ((Component)fishingFloat).GetComponent<MultiLineFishingFloatMarker>(); if ((Object)(object)component == (Object)null) { return false; } MultiLineBaitReservation baitReturnSource = (component.ReservedBait.IsValid ? component.ReservedBait : component.BaitReturnSource); if (baitReturnSource.IsValid) { MarkFishingBaitReturnSource(((Component)fishingFloat).gameObject, baitReturnSource); return TryReturnTrackedBaitToOriginalSource(((Component)fishingFloat).gameObject, fishingFloat); } return component.IsAdditionalLine; } internal static void TrySettleBaitAfterProjectileGroundHit(Projectile projectile, Collider collider, bool water) { if (water || (Object)(object)projectile == (Object)null || !ProjectileAccess.GetDidHit(projectile) || !ProjectileAccess.WillDestroyAfterHit(projectile, collider)) { return; } MultiLineFishingFloatMarker component = ((Component)projectile).GetComponent<MultiLineFishingFloatMarker>(); if (!((Object)(object)component == (Object)null) && component.IsAdditionalLine) { FishingBaitReturnTracker component2 = ((Component)projectile).GetComponent<FishingBaitReturnTracker>(); if ((Object)(object)component2 != (Object)null && component2.TrySettle()) {