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.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.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())
{