Decompiled source of Valheim Deep Waters v1.0.2

plugins/ValheimDeepWaters.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using SoftReferenceableAssets;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ValheimDeepWaters")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+de52a60d8b7aa1da3a2f129cdbd6762ff2e70f75")]
[assembly: AssemblyProduct("ValheimDeepWaters")]
[assembly: AssemblyTitle("ValheimDeepWaters")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ValheimDeepWaters
{
	internal static class FishingBoat
	{
		[HarmonyPatch(typeof(Player), "UpdateDoodadControls")]
		private static class KeepRowerFacing
		{
			private static readonly FieldInfo? Controller = AccessTools.Field(typeof(Player), "m_doodadController");

			private static bool Prefix(Player __instance)
			{
				object? obj = Controller?.GetValue(__instance);
				ShipControlls val = (ShipControlls)((obj is ShipControlls) ? obj : null);
				if (val == null || (Object)(object)val.m_ship == (Object)null || (Object)(object)((Component)val.m_ship).GetComponent<FishingBoatOars>() == (Object)null)
				{
					return true;
				}
				if (!val.IsValid())
				{
					__instance.StopDoodadControl();
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Character), "UpdateRotation")]
		private static class SeatedStayPut
		{
			private static readonly FieldInfo? AttachPoint = AccessTools.Field(typeof(Player), "m_attachPoint");

			private static bool Prefix(Character __instance, ref float __result)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val == null || !((Character)val).IsAttached())
				{
					return true;
				}
				object? obj = AttachPoint?.GetValue(val);
				Transform val2 = (Transform)((obj is Transform) ? obj : null);
				if (val2 == null || (Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponentInParent<FishingBoatOars>() == (Object)null)
				{
					return true;
				}
				__result = 0f;
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerProfile), "SetLogoutPoint")]
		private static class LogoutStandingInBoat
		{
			private static readonly FieldInfo? AttachPoint = AccessTools.Field(typeof(Player), "m_attachPoint");

			internal static readonly Vector3 StandSpot = new Vector3(0f, 0.4f, -0.7f);

			private static void Prefix(ref Vector3 point)
			{
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: 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)
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || !((Character)localPlayer).IsAttached())
				{
					return;
				}
				object? obj = AttachPoint?.GetValue(localPlayer);
				Transform val = (Transform)((obj is Transform) ? obj : null);
				if (val != null && !((Object)(object)val == (Object)null))
				{
					FishingBoatOars componentInParent = ((Component)val).GetComponentInParent<FishingBoatOars>();
					if (!((Object)(object)componentInParent == (Object)null))
					{
						point = ((Component)componentInParent).transform.TransformPoint(StandSpot);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Ship), "Forward")]
		private static class RowingOnly
		{
			private static bool Prefix(Ship __instance)
			{
				//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_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				if ((Object)(object)((Component)__instance).GetComponent<FishingBoatOars>() == (Object)null)
				{
					return true;
				}
				Speed speedSetting = __instance.GetSpeedSetting();
				if ((int)speedSetting != 0)
				{
					return (int)speedSetting == 1;
				}
				return true;
			}
		}

		public const string PrefabName = "VDW_FishingBoat";

		private const string ModelKey = "fishing_boat";

		internal const float Length = 3.97f;

		internal const float Beam = 1.63f;

		internal const float Height = 0.929f;

		internal const float Waterline = 0.3f;

		internal const float BenchTop = 0.538f;

		internal const float BenchToBow = 0.41f;

		internal const float OarInboard = 0.51f;

		internal const float SternSeatTop = 0.556f;

		internal const float OarlockToSternSeat = 0.93f;

		internal const float BowDeckTop = 0.762f;

		internal const float BowStandX = -0.16f;

		internal const float BowStandZ = 1.1f;

		internal const float BowFloor = 0.36f;

		internal const float BowStandTurn = 12f;

		internal static readonly Vector3 RowerSeat = new Vector3(0f, 0.14f, -0.18f);

		internal const float PassengerDrop = 0.36f;

		private const string WreckName = "vdw_vfx_Destroyed_FishingBoat";

		private static readonly float[] WreckPlanks = new float[7] { 1.6f, 1.3f, 1.1f, 0.9f, 0.6f, 0.45f, 0.35f };

		private static readonly Vector2 PlankTiling = new Vector2(0.4f, 0.7f);

		internal static Vector2 PlankTilingPerMetre => PlankTiling;

		public static void Register()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			GameObject bundlePrefab = CustomModels.GetBundlePrefab("fishing_boat");
			if ((Object)(object)bundlePrefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Fishing Boat: no 'fishing_boat' model in the bundles; the boat isn't added.");
				return;
			}
			if ((Object)(object)PrefabManager.Instance.GetPrefab("Raft") == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Fishing Boat: vanilla 'Raft' not found; the boat isn't added.");
				return;
			}
			PieceConfig val = new PieceConfig();
			val.Name = Loc.Token("vdw_piece_fishing_boat", "Fishing Boat");
			val.Description = Loc.Token("vdw_piece_fishing_boat_desc", "A small rowing boat for one angler. Sit on the bench and row.");
			val.PieceTable = "Hammer";
			val.Category = "Misc";
			val.CraftingStation = "piece_workbench";
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("Wood", 24, 0, true),
				new RequirementConfig("Resin", 8, 0, true),
				new RequirementConfig("DeerHide", 4, 0, true)
			};
			CustomPiece val2 = new CustomPiece("VDW_FishingBoat", "Raft", val);
			if (Build(val2.PiecePrefab, bundlePrefab))
			{
				ItemIcons.Apply(val2.PiecePrefab, "fishing_boat");
				PieceManager.Instance.AddPiece(val2);
				Plugin.Log.LogDebug((object)"Fishing Boat added.");
			}
		}

		private static bool Build(GameObject prefab, GameObject model)
		{
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_055b: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Expected O, but got Unknown
			//IL_0638: Unknown result type (might be due to invalid IL or missing references)
			//IL_0648: Unknown result type (might be due to invalid IL or missing references)
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			//IL_072d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0732: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0708: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_085a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0869: Unknown result type (might be due to invalid IL or missing references)
			//IL_0870: Expected O, but got Unknown
			//IL_0820: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0910: Unknown result type (might be due to invalid IL or missing references)
			//IL_0929: Unknown result type (might be due to invalid IL or missing references)
			//IL_097e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0983: Unknown result type (might be due to invalid IL or missing references)
			//IL_0997: Unknown result type (might be due to invalid IL or missing references)
			//IL_099c: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ab: Expected O, but got Unknown
			//IL_09cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a60: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a65: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a98: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aa8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ab2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ac1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0af6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0afb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b00: Unknown result type (might be due to invalid IL or missing references)
			Ship ship = prefab.GetComponent<Ship>();
			ShipControlls val = (((Object)(object)ship != (Object)null) ? ship.m_shipControlls : null);
			if ((Object)(object)ship == (Object)null || (Object)(object)val == (Object)null || (Object)(object)ship.m_floatCollider == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Fishing Boat: the raft has no ship parts to build on; the boat isn't added.");
				return false;
			}
			Transform transform = prefab.transform;
			Ladder val2 = ((Component)transform).GetComponentsInChildren<Ladder>(true).FirstOrDefault();
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in componentsInChildren)
			{
				if (val3 is MeshRenderer || val3 is SkinnedMeshRenderer || val3 is LineRenderer)
				{
					val3.enabled = false;
				}
			}
			MonoBehaviour[] componentsInChildren2 = prefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val4 in componentsInChildren2)
			{
				if (((object)val4).GetType().Name.StartsWith("Magica"))
				{
					((Behaviour)val4).enabled = false;
				}
			}
			int layer = -1;
			Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val5 in componentsInChildren3)
			{
				if (!((Object)(object)val5 == (Object)(object)ship.m_floatCollider) && !val5.isTrigger && !((Component)val5).transform.IsChildOf(((Component)val).transform) && (!((Object)(object)val2 != (Object)null) || !((Component)val5).transform.IsChildOf(((Component)val2).transform)))
				{
					if (layer < 0)
					{
						layer = ((Component)val5).gameObject.layer;
					}
					val5.enabled = false;
				}
			}
			if (layer < 0)
			{
				layer = LayerMask.NameToLayer("vehicle");
			}
			GameObject val6 = Object.Instantiate<GameObject>(model, transform, false);
			((Object)val6).name = "vdw_model";
			val6.transform.localPosition = Vector3.zero;
			val6.transform.localRotation = Quaternion.identity;
			componentsInChildren3 = val6.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			WearNTear component = prefab.GetComponent<WearNTear>();
			DressInShipPlanks(val6.transform);
			if ((Object)(object)component != (Object)null)
			{
				component.m_new = (component.m_worn = (component.m_broken = val6));
				component.m_destroyedEffect = WoodBreakEffect(component.m_destroyedEffect, val6.transform);
			}
			List<Transform> list = (from t in val6.GetComponentsInChildren<Transform>(true)
				where ((Object)t).name.StartsWith("oar.")
				select t).ToList();
			float num = ((list.Count > 0) ? list.Average((Transform t) => t.localPosition.z) : (-0.4f));
			float oarlockY = ((list.Count > 0) ? list.Average((Transform t) => t.localPosition.y) : 0.65f);
			float num2 = num + 0.41f;
			GameObject cols = new GameObject("vdw_colliders");
			cols.layer = layer;
			cols.transform.SetParent(transform, false);
			Box("floor", new Vector3(0f, 0.17f, -0.1f), new Vector3(1.1736001f, 0.2f, 2.8584f));
			Box("floor_bow", new Vector3(0f, 0.25f, 1.15f), new Vector3(0.6846f, 0.2f, 0.5f));
			Box("bow_deck", new Vector3(0f, 0.722f, 1.62f), new Vector3(0.5216f, 0.08f, 0.45f));
			Box("side_r", new Vector3(0.7661f, 0.4645f, 0f), new Vector3(0.08f, 0.929f, 3.0965998f));
			Box("side_l", new Vector3(-0.7661f, 0.4645f, 0f), new Vector3(0.08f, 0.929f, 3.0965998f));
			Box("bow", new Vector3(0f, 0.4645f, 1.7468f), new Vector3(0.7335f, 0.929f, 0.25f));
			Box("stern", new Vector3(0f, 0.4645f, -1.8262f), new Vector3(0.97800004f, 0.929f, 0.12f));
			Box("bench", new Vector3(0f, 0.508f, num2), new Vector3(1.3855001f, 0.06f, 0.32f));
			Transform transform2 = ((Component)ship.m_floatCollider).transform;
			transform2.localPosition = new Vector3(0f, 0.3f, 0f);
			transform2.localRotation = Quaternion.identity;
			transform2.localScale = Vector3.one;
			ship.m_floatCollider.center = Vector3.zero;
			ship.m_floatCollider.size = new Vector3(1.467f, 0.5f, 3.573f);
			ship.m_waterLevelOffset = 1.6f;
			ship.m_stearForceOffset = -1.588f;
			ship.m_stearForce = 0.5f;
			ship.m_backwardForce = 1.1f;
			ship.m_hasSail = false;
			ship.m_sailForceFactor = 0f;
			ship.m_rudderObject = null;
			ship.m_minWaterImpactForce = 6.5f;
			ship.m_waterImpactDamage = 5f;
			foreach (Collider item in from c in prefab.GetComponentsInChildren<Collider>(true)
				where c.isTrigger && c is BoxCollider && (Object)(object)c != (Object)(object)ship.m_floatCollider
				select c)
			{
				BoxCollider val7 = (BoxCollider)item;
				((Component)item).transform.localPosition = Vector3.zero;
				((Component)item).transform.localRotation = Quaternion.identity;
				((Component)item).transform.localScale = Vector3.one;
				val7.center = new Vector3(0f, 1.2f, 0f);
				val7.size = new Vector3(1.63f, 2.4f, 3.97f);
			}
			Transform transform3 = ((Component)val).transform;
			transform3.localPosition = new Vector3(0f, 0.538f, num2);
			transform3.localRotation = Quaternion.LookRotation(Vector3.back, Vector3.up);
			if ((Object)(object)val.m_attachPoint != (Object)null)
			{
				val.m_attachPoint.localPosition = Vector3.zero;
				val.m_attachPoint.localRotation = Quaternion.identity;
			}
			val.m_attachAnimation = "attach_sitship";
			val.m_detachOffset = new Vector3(0f, 0.5f, 0f);
			val.m_hoverText = Loc.Token("vdw_boat_row", "Row");
			BoxCollider[] componentsInChildren4 = ((Component)transform3).GetComponentsInChildren<BoxCollider>(true);
			foreach (BoxCollider val8 in componentsInChildren4)
			{
				if (!((Collider)val8).isTrigger)
				{
					((Component)val8).transform.localPosition = Vector3.zero;
					((Component)val8).transform.localRotation = Quaternion.identity;
					val8.center = new Vector3(0f, 0.45f, 0.1f);
					val8.size = new Vector3(1.3855001f, 0.9f, 0.75f);
					int num3 = LayerMask.NameToLayer("piece_nonsolid");
					if (num3 >= 0)
					{
						((Component)val8).gameObject.layer = num3;
					}
				}
			}
			if ((Object)(object)ship.m_controlGuiPos != (Object)null)
			{
				ship.m_controlGuiPos.localPosition = new Vector3(0f, 1.938f, num2);
			}
			float num4 = num - 0.93f;
			Box("stern_seat", new Vector3(0f, 0.526f, num4), new Vector3(0.8965f, 0.06f, 0.38f));
			GameObject val9 = new GameObject("vdw_passenger_seat");
			val9.layer = (from c in ((Component)transform3).GetComponentsInChildren<Collider>(true)
				select ((Component)c).gameObject.layer).DefaultIfEmpty(layer).First();
			val9.transform.SetParent(transform, false);
			val9.transform.localPosition = new Vector3(0f, 0.19599998f, num4);
			val9.transform.localRotation = Quaternion.LookRotation(Vector3.forward, Vector3.up);
			BoxCollider obj = val9.AddComponent<BoxCollider>();
			obj.center = new Vector3(0f, 0.71000004f, 0f);
			obj.size = new Vector3(1.3855001f, 0.95f, 0.8f);
			Chair obj2 = val9.AddComponent<Chair>();
			obj2.m_name = Loc.Token("vdw_boat_passenger", "Passenger seat");
			obj2.m_attachPoint = val9.transform;
			obj2.m_attachAnimation = "attach_sitship";
			obj2.m_inShip = true;
			obj2.m_detachOffset = new Vector3(0f, 0.5f, 0f);
			obj2.m_useDistance = 2f;
			GameObject val10 = new GameObject("vdw_bow_holdfast")
			{
				layer = val9.layer
			};
			val10.transform.SetParent(transform, false);
			val10.transform.localPosition = new Vector3(-0.16f, 0.36f, 1.1f);
			val10.transform.localRotation = Quaternion.AngleAxis(12f, Vector3.up);
			BoxCollider obj3 = val10.AddComponent<BoxCollider>();
			obj3.center = new Vector3(0f, 0.6f, 0.15f);
			obj3.size = new Vector3(0.652f, 1f, 0.4f);
			Chair obj4 = val10.AddComponent<Chair>();
			obj4.m_name = "$ship_holdfast";
			obj4.m_attachPoint = val10.transform;
			obj4.m_attachAnimation = "attach_dragon";
			obj4.m_inShip = true;
			obj4.m_detachOffset = Vector3.zero;
			obj4.m_useDistance = 2f;
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).transform.localPosition = new Vector3(0.865f, 0.1f, num2 - 0.6f);
				((Component)val2).transform.localRotation = Quaternion.LookRotation(Vector3.left, Vector3.up);
				Transform transform4 = new GameObject("vdw_ladder_target").transform;
				transform4.SetParent(transform, false);
				transform4.localPosition = new Vector3(0.29340002f, 0.3f, num2 - 0.6f);
				transform4.localRotation = Quaternion.LookRotation(Vector3.left, Vector3.up);
				val2.m_targetPos = transform4;
			}
			prefab.AddComponent<FishingBoatOars>().Setup(val6.transform, list, oarlockY, val10.transform);
			return true;
			void Box(string name, Vector3 centre, Vector3 size)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: 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_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				GameObject val11 = new GameObject(name)
				{
					layer = layer
				};
				val11.transform.SetParent(cols.transform, false);
				BoxCollider obj5 = val11.AddComponent<BoxCollider>();
				obj5.center = centre;
				obj5.size = size;
			}
		}

		private static EffectList WoodBreakEffect(EffectList? raft, Transform boat)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			EffectData[] array = (EffectData[])(((object)raft?.m_effectPrefabs) ?? ((object)new EffectData[0]));
			foreach (EffectData val in array)
			{
				if ((Object)(object)val?.m_prefab == (Object)null)
				{
					continue;
				}
				if (!((Object)val.m_prefab).name.StartsWith("vfx_Destroyed_Raft"))
				{
					list.Add(val);
					continue;
				}
				GameObject val2 = Wreckage(boat);
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(new EffectData
					{
						m_prefab = val2,
						m_enabled = true
					});
				}
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("wood_wall_half");
			WearNTear val3 = ((prefab != null) ? prefab.GetComponent<WearNTear>() : null);
			if (val3?.m_destroyedEffect?.m_effectPrefabs != null)
			{
				list.AddRange(val3.m_destroyedEffect.m_effectPrefabs.Where((EffectData e) => (Object)(object)e?.m_prefab != (Object)null && ((Object)e.m_prefab).name.StartsWith("vfx")));
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}

		private static GameObject? Wreckage(Transform boat)
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = PrefabManager.Instance.GetPrefab("vdw_vfx_Destroyed_FishingBoat");
			if ((Object)(object)prefab != (Object)null)
			{
				return prefab;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("vdw_vfx_Destroyed_FishingBoat", "vfx_Destroyed_Raft");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			List<MeshFilter> list = (from f in ((Component)boat).GetComponentsInChildren<MeshFilter>(true)
				where ((Object)f).name.StartsWith("oar.") && (Object)(object)f.sharedMesh != (Object)null
				select f).ToList();
			Renderer? obj = ((IEnumerable<Renderer>)((Component)boat).GetComponentsInChildren<Renderer>(true)).FirstOrDefault((Func<Renderer, bool>)((Renderer r) => ((Object)r).name == "hull"));
			Material val2 = ((obj != null) ? obj.sharedMaterial : null);
			GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)3);
			Mesh sharedMesh = obj2.GetComponent<MeshFilter>().sharedMesh;
			Object.DestroyImmediate((Object)(object)obj2);
			int num = 0;
			int num2 = 0;
			foreach (MeshFilter item in (from f in val.GetComponentsInChildren<MeshFilter>(true)
				where (Object)(object)((Component)f).GetComponent<Rigidbody>() != (Object)null || (Object)(object)((Component)f).GetComponentInParent<Rigidbody>() != (Object)null
				select f).ToList())
			{
				Transform transform = ((Component)item).transform;
				MeshRenderer component = ((Component)item).GetComponent<MeshRenderer>();
				Collider[] components = ((Component)item).GetComponents<Collider>();
				for (int num3 = 0; num3 < components.Length; num3++)
				{
					Object.DestroyImmediate((Object)(object)components[num3]);
				}
				transform.localPosition *= 0.55f;
				transform.localScale = Vector3.one;
				bool flag = num >= WreckPlanks.Length && num2 < list.Count;
				if (flag)
				{
					MeshFilter val3 = list[num2++];
					item.sharedMesh = val3.sharedMesh;
					if ((Object)(object)component != (Object)null)
					{
						Renderer component2 = ((Component)val3).GetComponent<Renderer>();
						((Renderer)component).sharedMaterials = ((component2 != null) ? component2.sharedMaterials : null) ?? ((Renderer)component).sharedMaterials;
					}
				}
				else
				{
					if (num >= WreckPlanks.Length)
					{
						Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
						continue;
					}
					float num4 = WreckPlanks[num++];
					item.sharedMesh = sharedMesh;
					transform.localScale = new Vector3(0.17f, 0.03f, num4);
					if ((Object)(object)component != (Object)null && (Object)(object)val2 != (Object)null)
					{
						((Renderer)component).sharedMaterials = (Material[])(object)new Material[1] { val2 };
					}
				}
				BoxCollider obj3 = ((Component)item).gameObject.AddComponent<BoxCollider>();
				Bounds bounds = item.sharedMesh.bounds;
				obj3.center = ((Bounds)(ref bounds)).center;
				bounds = item.sharedMesh.bounds;
				obj3.size = ((Bounds)(ref bounds)).size;
				Rigidbody component3 = ((Component)item).GetComponent<Rigidbody>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.mass = (flag ? 3f : 2f);
				}
			}
			Plugin.Log.LogDebug((object)$"Fishing Boat: wreckage of {num} planks and {num2} oars.");
			return val;
		}

		internal static Material? FindShipPlanks()
		{
			string[] array = new string[2] { "VikingShip", "Karve" };
			foreach (string text in array)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				Material val = ((prefab != null) ? prefab.GetComponentsInChildren<Renderer>(true).SelectMany((Renderer r) => r.sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null && ((Object)m).name.StartsWith("worn_shipplank"))) : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static void DressInShipPlanks(Transform boat)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			Material val = FindShipPlanks();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Fishing Boat: Valheim's ship planks weren't found; the hull keeps its own planks.");
				return;
			}
			Material val2 = new Material(val)
			{
				name = "VDW_BoatPlanks"
			};
			Vector2 mainTextureScale = val2.mainTextureScale;
			string[] texturePropertyNames = val2.GetTexturePropertyNames();
			foreach (string text in texturePropertyNames)
			{
				if ((Object)(object)val2.GetTexture(text) != (Object)null && val2.GetTextureScale(text) == mainTextureScale)
				{
					val2.SetTextureScale(text, PlankTiling);
					val2.SetTextureOffset(text, Vector2.zero);
				}
			}
			Material val3 = new Material(val)
			{
				name = "VDW_BoatIron",
				mainTexture = (Texture)(object)Texture2D.whiteTexture
			};
			if (val3.HasProperty("_Color"))
			{
				val3.SetColor("_Color", new Color(0.13f, 0.13f, 0.14f));
			}
			Renderer[] componentsInChildren = ((Component)boat).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in componentsInChildren)
			{
				Material val5 = ((((Object)val4).name == "hull") ? val2 : (((Object)val4).name.StartsWith("oarlocks") ? val3 : null));
				if ((Object)(object)val5 != (Object)null)
				{
					val4.sharedMaterials = Enumerable.Repeat<Material>(val5, val4.sharedMaterials.Length).ToArray();
				}
			}
			Plugin.Log.LogDebug((object)$"Fishing Boat: hull in Valheim's ship planks ({((Object)val.shader).name}, vanilla tiling {mainTextureScale}).");
		}
	}
	internal sealed class FishingBoatOars : MonoBehaviour
	{
		[SerializeField]
		private Transform? _model;

		[SerializeField]
		private Transform[] _oars = (Transform[])(object)new Transform[0];

		[SerializeField]
		private Quaternion[] _rest = (Quaternion[])(object)new Quaternion[0];

		[SerializeField]
		private float _oarlockY;

		[SerializeField]
		private Transform? _holdfast;

		private Ship? _ship;

		private float _phase;

		private float _row;

		private float _gripReach;

		private const float Catch = 38f;

		private const float Finish = 32f;

		private const float PitchIn = 22f;

		private const float PitchOut = 9f;

		private const float Feather = 80f;

		private const float Drive = 0.42f;

		private static readonly FieldInfo? AttachPointField = AccessTools.Field(typeof(Player), "m_attachPoint");

		private static readonly string[] Fingers = new string[5] { "Index", "Middle", "Ring", "Pinky", "Thumb" };

		private static readonly Dictionary<int, Dictionary<Transform, Quaternion>> RestPose = new Dictionary<int, Dictionary<Transform, Quaternion>>();

		private ZNetView? _nview;

		private WaterVolume? _water;

		private float _trimSince = -1f;

		private bool _trimLogged;

		private const float RightingStiffness = 40f;

		private const float RightingDamping = 8f;

		private Rigidbody? _rb;

		private static readonly Dictionary<int, Dictionary<string, Transform>> BoneCache = new Dictionary<int, Dictionary<string, Transform>>();

		private static readonly string[] PosedBones = BuildPosedBones();

		private static readonly Dictionary<int, Dictionary<Transform, (Quaternion anim, Quaternion ours)>> Posed = new Dictionary<int, Dictionary<Transform, (Quaternion, Quaternion)>>();

		public void Setup(Transform model, List<Transform> oars, float oarlockY, Transform holdfast)
		{
			_holdfast = holdfast;
			_model = model;
			_oars = oars.ToArray();
			_rest = oars.Select((Transform o) => o.localRotation).ToArray();
			_oarlockY = oarlockY;
		}

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			_ship = ((Component)this).GetComponent<Ship>();
			Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.centerOfMass = new Vector3(0f, 0.3f, 0f);
			}
			_gripReach = 0.43f;
			_phase = Random.value;
		}

		private void Start()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Transform val = _ship?.m_shipControlls?.m_attachPoint;
			if (!((Object)(object)val == (Object)null))
			{
				val.SetPositionAndRotation(((Component)this).transform.TransformPoint(FishingBoat.RowerSeat), ((Component)this).transform.rotation * Quaternion.LookRotation(Vector3.back, Vector3.up));
			}
		}

		private void SnapSeated()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (!((Object)(object)allPlayer == (Object)null) && ((Character)allPlayer).IsAttached())
				{
					object? obj = AttachPointField?.GetValue(allPlayer);
					Transform val = (Transform)((obj is Transform) ? obj : null);
					if (val != null && !((Object)(object)val == (Object)null) && val.IsChildOf(((Component)this).transform))
					{
						((Component)allPlayer).transform.SetPositionAndRotation(val.position, val.rotation);
					}
				}
			}
			Player val2 = (((Object)(object)_ship != (Object)null) ? Rower() : null);
			Transform val3 = _ship?.m_shipControlls?.m_attachPoint;
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)Player.m_localPlayer && (Object)(object)val3 != (Object)null)
			{
				((Component)val2).transform.SetPositionAndRotation(val3.position, val3.rotation);
			}
		}

		private static bool NearSeat(Player p, Transform? seat)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)seat != (Object)null)
			{
				return Vector3.Distance(((Component)p).transform.position, seat.position) < 1.2f;
			}
			return false;
		}

		private void Update()
		{
			SnapSeated();
		}

		private void LateUpdate()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_ship == (Object)null || (Object)(object)_model == (Object)null || _oars.Length == 0)
			{
				return;
			}
			SnapSeated();
			float deltaTime = Time.deltaTime;
			Speed speedSetting = _ship.GetSpeedSetting();
			bool flag = (int)speedSetting == 1;
			bool flag2 = (int)speedSetting != 0 && (Object)(object)_ship.m_shipControlls != (Object)null && _ship.m_shipControlls.HaveValidUser();
			_row = Mathf.MoveTowards(_row, flag2 ? 1f : 0f, deltaTime * 1.5f);
			_phase = Mathf.Repeat(_phase + (flag ? (-0.6f) : 0.75f) * deltaTime * _row, 1f);
			float rudderValue = _ship.GetRudderValue();
			Dictionary<int, Vector3> dictionary = new Dictionary<int, Vector3>();
			float sweep = 0f;
			Vector3 val2 = default(Vector3);
			Vector3 val3 = default(Vector3);
			for (int i = 0; i < _oars.Length; i++)
			{
				Transform val = _oars[i];
				int num = ((val.localPosition.x >= 0f) ? 1 : (-1));
				float num2 = 1f - 0.75f * Mathf.Clamp01(rudderValue * (float)num * (flag ? (-1f) : 1f));
				Stroke(_phase, out var sweep2, out var pitch, out var feather);
				sweep2 *= num2 * _row;
				feather *= _row;
				pitch = Mathf.Lerp(3f, pitch, _row);
				if (i == 0)
				{
					sweep = sweep2;
				}
				float num3 = sweep2 * (MathF.PI / 180f);
				float num4 = pitch * (MathF.PI / 180f);
				((Vector3)(ref val2))..ctor((float)num * Mathf.Cos(num3) * Mathf.Cos(num4), 0f - Mathf.Sin(num4), Mathf.Sin(num3) * Mathf.Cos(num4));
				((Vector3)(ref val3))..ctor((float)num, 0f, 0f);
				Vector3 val4 = Vector3.ProjectOnPlane(Vector3.up, val2);
				Vector3 normalized = ((Vector3)(ref val4)).normalized;
				Quaternion val5 = Quaternion.LookRotation(val2, normalized) * Quaternion.Inverse(Quaternion.LookRotation(val3, Vector3.up));
				val5 = Quaternion.AngleAxis(feather * (float)num, val2) * val5;
				val.localRotation = val5 * _rest[i];
				dictionary[num] = _model.TransformPoint(val.localPosition - val2 * _gripReach);
			}
			Player val6 = Rower();
			if ((Object)(object)val6 != (Object)null)
			{
				PoseRower(val6, dictionary, sweep);
			}
			PoseHoldfast();
		}

		private void PoseHoldfast()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_holdfast == (Object)null)
			{
				return;
			}
			Player closestPlayer = Player.GetClosestPlayer(_holdfast.position, 0.3f);
			if ((Object)(object)closestPlayer == (Object)null || ((Object)(object)closestPlayer == (Object)(object)Player.m_localPlayer && !((Character)closestPlayer).IsAttached()))
			{
				return;
			}
			BeginPose(closestPlayer);
			try
			{
				PoseHoldfastArms(closestPlayer);
			}
			finally
			{
				EndPose(closestPlayer);
			}
		}

		private void PoseHoldfastArms(Player p)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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)
			//IL_00e4: 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)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			(string, int)[] array = new(string, int)[2]
			{
				("Left", -1),
				("Right", 1)
			};
			for (int i = 0; i < array.Length; i++)
			{
				(string, int) tuple = array[i];
				string item = tuple.Item1;
				int item2 = tuple.Item2;
				Transform val = Bone(p, item + "Arm");
				Transform val2 = Bone(p, item + "ForeArm");
				Transform val3 = Bone(p, item + "Hand");
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null))
				{
					Transform transform = ((Component)p).transform;
					Vector3 target = val.position - Vector3.up * 0.46f + transform.right * ((float)item2 * 0.09f) + transform.forward * 0.08f;
					Vector3 pole = val.position - Vector3.up * 0.3f - transform.forward * 0.4f + transform.right * ((float)item2 * 0.15f);
					SolveArm(val, val2, val3, target, pole);
					Vector3 val4 = val3.position - val2.position;
					Vector3 val5 = -Vector3.up + transform.forward * 0.12f + transform.right * ((float)item2 * 0.06f);
					if (((Vector3)(ref val4)).sqrMagnitude > 1E-06f)
					{
						val2.rotation = Quaternion.FromToRotation(val4, val5) * val2.rotation;
					}
					RelaxHand(p, item, val2, val3, transform.forward);
					RelaxFingers(p, item);
				}
			}
		}

		private static void RelaxFingers(Player p, string prefix)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			string[] fingers = Fingers;
			foreach (string text in fingers)
			{
				for (int j = 1; j <= 3; j++)
				{
					Transform val = Bone(p, prefix + "Hand" + text + j);
					if ((Object)(object)val != (Object)null)
					{
						Quaternion? val2 = RestLocal(p, val);
						if (val2.HasValue)
						{
							Quaternion valueOrDefault = val2.GetValueOrDefault();
							val.localRotation = Quaternion.Slerp(val.localRotation, valueOrDefault, (text == "Thumb") ? 0.45f : 0.55f);
						}
					}
				}
			}
		}

		internal static void CurlFingers(Player p, string prefix, Vector3 axis)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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)
			if (((Vector3)(ref axis)).sqrMagnitude < 1E-06f)
			{
				return;
			}
			float[] array = new float[3] { 50f, 65f, 45f };
			string[] fingers = Fingers;
			foreach (string text in fingers)
			{
				if (text == "Thumb")
				{
					continue;
				}
				for (int j = 1; j <= 3; j++)
				{
					Transform val = Bone(p, prefix + "Hand" + text + j);
					if ((Object)(object)val == (Object)null)
					{
						break;
					}
					Quaternion? val2 = RestLocal(p, val);
					if (val2.HasValue)
					{
						Quaternion valueOrDefault = val2.GetValueOrDefault();
						val.localRotation = valueOrDefault;
					}
					val.rotation = Quaternion.AngleAxis(array[j - 1], axis) * val.rotation;
				}
			}
		}

		private static Quaternion? RestLocal(Player p, Transform bone)
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)p).GetInstanceID();
			if (!RestPose.TryGetValue(instanceID, out Dictionary<Transform, Quaternion> value))
			{
				value = new Dictionary<Transform, Quaternion>();
				SkinnedMeshRenderer val = ((Component)p).GetComponent<VisEquipment>()?.m_bodyModel;
				if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null)
				{
					Transform[] bones = val.bones;
					Matrix4x4[] bindposes = val.sharedMesh.bindposes;
					Dictionary<Transform, int> dictionary = new Dictionary<Transform, int>();
					for (int i = 0; i < bones.Length && i < bindposes.Length; i++)
					{
						if ((Object)(object)bones[i] != (Object)null)
						{
							dictionary[bones[i]] = i;
						}
					}
					foreach (KeyValuePair<Transform, int> item in dictionary)
					{
						Transform parent = item.Key.parent;
						if (!((Object)(object)parent == (Object)null) && dictionary.TryGetValue(parent, out var value2))
						{
							Matrix4x4 val2 = bindposes[value2] * ((Matrix4x4)(ref bindposes[item.Value])).inverse;
							value[item.Key] = ((Matrix4x4)(ref val2)).rotation;
						}
					}
				}
				RestPose[instanceID] = value;
			}
			if (!value.TryGetValue(bone, out var value3))
			{
				return null;
			}
			return value3;
		}

		private static void RelaxHand(Player p, string prefix, Transform lower, Transform hand, Vector3 forward)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = hand.position - lower.position;
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				return;
			}
			((Vector3)(ref val)).Normalize();
			Transform val2 = Bone(p, prefix + "HandMiddle1");
			if ((Object)(object)val2 != (Object)null)
			{
				Vector3 val3 = val2.position - hand.position;
				if (((Vector3)(ref val3)).sqrMagnitude > 1E-06f)
				{
					hand.rotation = Quaternion.FromToRotation(val3, val) * hand.rotation;
				}
			}
			Transform val4 = Bone(p, prefix + "HandThumb1");
			if ((Object)(object)val4 != (Object)null)
			{
				Vector3 val5 = Vector3.ProjectOnPlane(val4.position - hand.position, val);
				Vector3 val6 = Vector3.ProjectOnPlane(forward, val);
				if (((Vector3)(ref val5)).sqrMagnitude > 1E-06f && ((Vector3)(ref val6)).sqrMagnitude > 1E-06f)
				{
					hand.rotation = Quaternion.AngleAxis(Vector3.SignedAngle(val5, val6, val), val) * hand.rotation;
				}
			}
		}

		private void KeepUpright()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rb == (Object)null) || !((Object)(object)(_rb = ((Component)this).GetComponent<Rigidbody>()) == (Object)null))
			{
				Vector3 val = Vector3.Cross(((Component)this).transform.up, Vector3.up);
				Vector3 angularVelocity = _rb.angularVelocity;
				angularVelocity -= Vector3.Project(angularVelocity, Vector3.up);
				_rb.AddTorque(val * 40f - angularVelocity * 8f, (ForceMode)5);
			}
		}

		private void FixedUpdate()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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)_ship == (Object)null)
			{
				return;
			}
			if ((Object)(object)_nview == (Object)null)
			{
				_nview = ((Component)this).GetComponent<ZNetView>();
			}
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner())
			{
				return;
			}
			KeepUpright();
			if (Vector3.Dot(((Component)this).transform.up, Vector3.up) < 0.7f)
			{
				return;
			}
			float num = Floating.GetWaterLevel(((Component)this).transform.position, ref _water) - ((Component)this).transform.position.y;
			if (!(num < -1f) && !(num > 3f))
			{
				float num2 = num - 0.3f;
				_ship.m_waterLevelOffset = Mathf.Clamp(_ship.m_waterLevelOffset + num2 * 0.8f * Time.fixedDeltaTime, -2f, 4f);
				if (_trimSince < 0f)
				{
					_trimSince = Time.time;
				}
				if (!_trimLogged && Time.time - _trimSince > 20f)
				{
					_trimLogged = true;
					Plugin.Log.LogDebug((object)$"Fishing Boat: trimmed to float at its waterline (water level offset {_ship.m_waterLevelOffset:0.000}, draft {num:0.00} m).");
				}
			}
		}

		private static void Stroke(float p, out float sweep, out float pitch, out float feather)
		{
			if (p < 0.42f)
			{
				float num = p / 0.42f;
				sweep = Mathf.Lerp(38f, -32f, Ease(num));
				float num2 = Mathf.Clamp01(num / 0.12f) * Mathf.Clamp01((1f - num) / 0.12f);
				pitch = Mathf.Lerp(9f, 22f, num2);
				feather = 0f;
			}
			else
			{
				float num3 = (p - 0.42f) / 0.58000004f;
				sweep = Mathf.Lerp(-32f, 38f, Ease(num3));
				pitch = 9f;
				feather = 80f * Mathf.Clamp01(num3 / 0.25f) * Mathf.Clamp01((0.9f - num3) / 0.2f);
			}
		}

		private static float Ease(float u)
		{
			return 0.5f - 0.5f * Mathf.Cos(u * MathF.PI);
		}

		private Player? Rower()
		{
			ShipControlls shipControlls = _ship.m_shipControlls;
			if ((Object)(object)shipControlls == (Object)null || !shipControlls.HaveValidUser())
			{
				return null;
			}
			long user = shipControlls.GetUser();
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)null && allPlayer.GetPlayerID() == user && (((Object)(object)allPlayer == (Object)(object)Player.m_localPlayer) ? ((Character)allPlayer).IsAttached() : NearSeat(allPlayer, shipControlls.m_attachPoint)))
				{
					return allPlayer;
				}
			}
			return null;
		}

		internal static Transform? Bone(Player p, string name)
		{
			int instanceID = ((Object)p).GetInstanceID();
			if (!BoneCache.TryGetValue(instanceID, out Dictionary<string, Transform> value))
			{
				value = new Dictionary<string, Transform>();
				SkinnedMeshRenderer val = ((Component)p).GetComponent<VisEquipment>()?.m_bodyModel;
				if ((Object)(object)val != (Object)null)
				{
					Transform[] bones = val.bones;
					foreach (Transform val2 in bones)
					{
						if ((Object)(object)val2 != (Object)null && !value.ContainsKey(((Object)val2).name))
						{
							value[((Object)val2).name] = val2;
						}
					}
				}
				BoneCache[instanceID] = value;
			}
			if (!value.TryGetValue(name, out var value2) || !((Object)(object)value2 != (Object)null))
			{
				return null;
			}
			return value2;
		}

		private static string[] BuildPosedBones()
		{
			List<string> list = new List<string> { "Spine", "Spine1", "Spine2" };
			string[] array = new string[2] { "Left", "Right" };
			foreach (string text in array)
			{
				list.Add(text + "Arm");
				list.Add(text + "ForeArm");
				list.Add(text + "Hand");
				string[] fingers = Fingers;
				foreach (string text2 in fingers)
				{
					for (int k = 1; k <= 3; k++)
					{
						list.Add(text + "Hand" + text2 + k);
					}
				}
			}
			return list.ToArray();
		}

		internal static void BeginPose(Player p)
		{
			//IL_0080: 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_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_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!Posed.TryGetValue(((Object)p).GetInstanceID(), out Dictionary<Transform, (Quaternion, Quaternion)> value))
			{
				value = (Posed[((Object)p).GetInstanceID()] = new Dictionary<Transform, (Quaternion, Quaternion)>());
			}
			string[] posedBones = PosedBones;
			foreach (string name in posedBones)
			{
				Transform val = Bone(p, name);
				if (!((Object)(object)val == (Object)null))
				{
					if (value.TryGetValue(val, out var value2) && val.localRotation == value2.Item2)
					{
						val.localRotation = value2.Item1;
					}
					value[val] = (val.localRotation, val.localRotation);
				}
			}
		}

		internal static void BlendPose(Player p, float weight)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (weight >= 1f || !Posed.TryGetValue(((Object)p).GetInstanceID(), out Dictionary<Transform, (Quaternion, Quaternion)> value))
			{
				return;
			}
			foreach (KeyValuePair<Transform, (Quaternion, Quaternion)> item in value)
			{
				if ((Object)(object)item.Key != (Object)null)
				{
					item.Key.localRotation = Quaternion.Slerp(item.Value.Item1, item.Key.localRotation, weight);
				}
			}
		}

		internal static void EndPose(Player p)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!Posed.TryGetValue(((Object)p).GetInstanceID(), out Dictionary<Transform, (Quaternion, Quaternion)> value))
			{
				return;
			}
			foreach (Transform item in value.Keys.ToList())
			{
				if ((Object)(object)item != (Object)null)
				{
					value[item] = (value[item].Item1, item.localRotation);
				}
			}
		}

		private void PoseRower(Player p, Dictionary<int, Vector3> grips, float sweep)
		{
			BeginPose(p);
			try
			{
				PoseRowerArms(p, grips, sweep);
			}
			finally
			{
				EndPose(p);
			}
		}

		private void PoseRowerArms(Player p, Dictionary<int, Vector3> grips, float sweep)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Lerp(-12f, 20f, Mathf.InverseLerp(-32f, 38f, sweep)) * _row;
			Transform val = Bone(p, "Spine1");
			if ((Object)(object)val != (Object)null)
			{
				val.rotation = Quaternion.AngleAxis(num, ((Component)p).transform.right) * val.rotation;
			}
			(string, int)[] array = new(string, int)[2]
			{
				("Left", -1),
				("Right", 1)
			};
			for (int i = 0; i < array.Length; i++)
			{
				(string, int) tuple = array[i];
				string item = tuple.Item1;
				int item2 = tuple.Item2;
				Transform val2 = Bone(p, item + "Arm");
				Transform val3 = Bone(p, item + "ForeArm");
				Transform val4 = Bone(p, item + "Hand");
				if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
				{
					continue;
				}
				Vector3 target = Vector3.zero;
				bool flag = false;
				foreach (KeyValuePair<int, Vector3> grip in grips)
				{
					if (Vector3.Dot(grip.Value - ((Component)p).transform.position, ((Component)p).transform.right) * (float)item2 > 0f)
					{
						target = grip.Value;
						flag = true;
					}
				}
				if (flag)
				{
					Vector3 pole = val2.position + ((Component)p).transform.right * ((float)item2 * 0.6f) - Vector3.up * 0.4f - ((Component)p).transform.forward * 0.2f;
					SolveArm(val2, val3, val4, target, pole);
				}
			}
		}

		internal static void SolveArm(Transform upper, Transform lower, Transform hand, Vector3 target, Vector3 pole)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = upper.position;
			Vector3 position2 = lower.position;
			Vector3 position3 = hand.position;
			Vector3 val = position2 - position;
			float magnitude = ((Vector3)(ref val)).magnitude;
			val = position3 - position2;
			float magnitude2 = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 0.0001f) && !(magnitude2 < 0.0001f))
			{
				Vector3 val2 = target - position;
				float num = Mathf.Clamp(((Vector3)(ref val2)).magnitude, Mathf.Abs(magnitude - magnitude2) + 0.001f, magnitude + magnitude2 - 0.001f);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				float num2 = Mathf.Clamp((magnitude * magnitude + num * num - magnitude2 * magnitude2) / (2f * magnitude * num), -1f, 1f);
				Vector3 val3 = Vector3.ProjectOnPlane(pole - position, normalized);
				if (((Vector3)(ref val3)).sqrMagnitude < 1E-06f)
				{
					val3 = Vector3.ProjectOnPlane(Vector3.down, normalized);
				}
				Vector3 val4 = position + normalized * (magnitude * num2) + ((Vector3)(ref val3)).normalized * (magnitude * Mathf.Sqrt(1f - num2 * num2));
				upper.rotation = Quaternion.FromToRotation(position2 - position, val4 - position) * upper.rotation;
				position2 = lower.position;
				position3 = hand.position;
				lower.rotation = Quaternion.FromToRotation(position3 - position2, position + normalized * num - position2) * lower.rotation;
			}
		}
	}
	internal static class CommandRegistry
	{
		private class VdwGiveCommand : ConsoleCommand
		{
			public override string Name => "vdw_give";

			public override bool IsCheat => true;

			public override string Help => "Give Deep Waters fishing content. Usage: vdw_give [rod|rod_<id>|hook_<id>|tackle_<id>|tacklebox_t1..t4|buff_<id>|bait_id|fish_id] [amount]  (ids come from vdw_debug listrods / listhooks / listbuffs / listbait / listfish)";

			public override void Run(string[] args)
			{
				if (args.Length < 1)
				{
					Console.instance.Print("Usage: vdw_give rod 1 | vdw_give worm 20 | vdw_give trout 1");
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					return;
				}
				string what = args[0];
				int result = 1;
				if (args.Length >= 2)
				{
					int.TryParse(args[1], out result);
				}
				result = Math.Max(1, result);
				RodDefinition rodDefinition = null;
				if (what.Equals("rod", StringComparison.OrdinalIgnoreCase))
				{
					rodDefinition = ContentRegistry.Rods.FirstOrDefault();
				}
				else if (what.StartsWith("rod_", StringComparison.OrdinalIgnoreCase))
				{
					rodDefinition = ContentRegistry.Rods.FirstOrDefault((RodDefinition r) => r.Id.Equals(what.Substring(4), StringComparison.OrdinalIgnoreCase));
				}
				string text;
				if (rodDefinition != null)
				{
					text = ContentRegistry.RodPrefabName(rodDefinition);
				}
				else if (what.StartsWith("hook_", StringComparison.OrdinalIgnoreCase) && ContentRegistry.Hooks.ContainsKey(what.Substring(5)))
				{
					text = "VDW_Hook_" + what.Substring(5);
				}
				else if (what.StartsWith("tacklebox_", StringComparison.OrdinalIgnoreCase) && TackleBoxes.Tiers.Any((TackleBoxes.Tier t) => t.Id.Equals(what.Substring(10), StringComparison.OrdinalIgnoreCase)))
				{
					text = "VDW_TackleChest_" + what.Substring(10).ToLowerInvariant();
				}
				else if (what.StartsWith("tackle_", StringComparison.OrdinalIgnoreCase) && ContentRegistry.Tackle.ContainsKey(what.Substring(7)))
				{
					text = "VDW_Tackle_" + what.Substring(7);
				}
				else if (what.StartsWith("buff_", StringComparison.OrdinalIgnoreCase) && FishingBuffs.Buffs.ContainsKey(what.Substring(5)))
				{
					text = "VDW_Buff_" + what.Substring(5);
				}
				else if (ContentRegistry.Baits.ContainsKey(what))
				{
					text = "VDW_Bait_" + what;
				}
				else
				{
					if (!ContentRegistry.Fish.ContainsKey(what))
					{
						Console.instance.Print("Unknown item. See vdw_debug listfish / listbait / listrods / listhooks / listbuffs.");
						return;
					}
					text = "VDW_Fish_" + what;
				}
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if ((Object)(object)((prefab != null) ? prefab.GetComponent<ItemDrop>() : null) == (Object)null)
				{
					Console.instance.Print("Prefab is not available yet: " + text);
					return;
				}
				((Humanoid)localPlayer).GetInventory().AddItem(text, result, 1, 0, 0L, "", false, false);
				Console.instance.Print($"Added {text} x{result}");
			}
		}

		private class VdwDebugCommand : ConsoleCommand
		{
			public override string Name => "vdw_debug";

			public override bool IsCheat => true;

			public override string Help => "Deep Waters testing tools. Usage: vdw_debug [bite | catch <fish> | boss <fish> | worms | horn | resetlog | rank <points> | resetrank | master <fish> <count> | variant <golden|albino> | rarefish <fish> <golden|albino> | wear <crown|pearl|rune> [axis value] | paint <chest|legs|both|alpha|off|dump> | tokens | listrods | listhooks | listbuffs | listfish | listbait]";

			public override void Run(string[] args)
			{
				//IL_0384: Unknown result type (might be due to invalid IL or missing references)
				//IL_0389: Unknown result type (might be due to invalid IL or missing references)
				//IL_038e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0399: Unknown result type (might be due to invalid IL or missing references)
				//IL_039b: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a2: Invalid comparison between Unknown and I4
				if (args.Length < 1)
				{
					Console.instance.Print(((ConsoleCommand)this).Help);
				}
				else if (args[0].Equals("bite", StringComparison.OrdinalIgnoreCase))
				{
					FishingController.DebugQuickBite = true;
					Console.instance.Print("Next cast: a fish starts right by the bait and bites with no nibbles.");
				}
				else if (args[0].Equals("boss", StringComparison.OrdinalIgnoreCase))
				{
					string text = string.Join(", ", BossFish.All.Select((BossInfo b) => b.FishId));
					if (args.Length < 2 || BossFish.ForFish(args[1]) == null)
					{
						Console.instance.Print("Usage: vdw_debug boss <fish id>   (" + text + ")");
						return;
					}
					FishingController.DebugBoss = args[1];
					Console.instance.Print("Next cast summons " + args[1] + ", wherever you are and whatever the bait.");
				}
				else if (args[0].Equals("catch", StringComparison.OrdinalIgnoreCase))
				{
					if (args.Length < 2 || !ContentRegistry.Fish.ContainsKey(args[1]))
					{
						Console.instance.Print("Usage: vdw_debug catch <fish id>   (ids from vdw_debug listfish)");
						return;
					}
					FishingController.DebugCatch = args[1];
					Console.instance.Print("Next cast: a " + args[1] + " comes straight to the bait and bites.");
				}
				else if (args[0].Equals("paint", StringComparison.OrdinalIgnoreCase))
				{
					if (!((Object)(object)Player.m_localPlayer == (Object)null))
					{
						Console.instance.Print(ArmorPaintTest.Run(Player.m_localPlayer, (args.Length > 1) ? args[1].ToLowerInvariant() : ""));
					}
				}
				else if (args[0].Equals("worms", StringComparison.OrdinalIgnoreCase))
				{
					Console.instance.Print(BaitSources.DescribeNearby());
				}
				else if (args[0].Equals("horn", StringComparison.OrdinalIgnoreCase))
				{
					int num = (((Object)(object)Player.m_localPlayer != (Object)null) ? HornOfAegir.ResetRest(Player.m_localPlayer) : 0);
					Console.instance.Print((num > 0) ? "The Horn of Ægir is rested and can be blown again." : "No resting Horn of Ægir in your inventory.");
				}
				else if (args[0].Equals("resetlog", StringComparison.OrdinalIgnoreCase))
				{
					if ((Object)(object)Player.m_localPlayer != (Object)null)
					{
						Player.m_localPlayer.m_customData.Remove("vdw_catchlog");
					}
					Console.instance.Print("Catch log cleared.");
				}
				else if (args[0].Equals("rank", StringComparison.OrdinalIgnoreCase))
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)localPlayer == (Object)null))
					{
						int result;
						int points = ((args.Length > 1 && int.TryParse(args[1], out result)) ? result : 100);
						string text2 = AnglerRanks.DebugAdd(localPlayer, points);
						Console.instance.Print(string.Format("Rank points: {0} ({1}).{2}", AnglerRanks.Points(localPlayer), AnglerRanks.Ranks[AnglerRanks.RankIndex(localPlayer)].Name, text2.Replace("\n", " ")));
					}
				}
				else if (args[0].Equals("master", StringComparison.OrdinalIgnoreCase))
				{
					Player localPlayer2 = Player.m_localPlayer;
					if ((Object)(object)localPlayer2 == (Object)null || args.Length < 2 || !ContentRegistry.Fish.TryGetValue(args[1], out FishDefinition value))
					{
						Console.instance.Print("Usage: vdw_debug master <fish id> [count]  (listfish for ids)");
						return;
					}
					int result2;
					int num2 = ((args.Length > 2 && int.TryParse(args[2], out result2)) ? result2 : 50);
					int countBefore = Mastery.Count(localPlayer2, value.Id);
					CatchLog.SetCount(localPlayer2, value.Id, num2);
					Endgame.RefreshLureCosts(localPlayer2);
					string text3 = Mastery.OnCatch(value, countBefore, num2);
					foreach (string item in CatchLog.ClaimRewards(localPlayer2))
					{
						text3 = text3 + " " + item;
					}
					Biome val = Heightmap.FindBiome(((Component)localPlayer2).transform.position);
					Rewards.RecordCaughtIn(localPlayer2, value.Id, val, (int)val == 256, deep: false);
					text3 += Rewards.ClaimBiomeSets(localPlayer2);
					Console.instance.Print(string.Format("{0}: {1} caught, mastery {2}.{3}", value.Name, num2, (Mastery.Tier(localPlayer2, value) == 0) ? "none" : Mastery.TierNames[Mastery.Tier(localPlayer2, value)], text3.Replace("\n", " ")));
				}
				else if (args[0].Equals("variant", StringComparison.OrdinalIgnoreCase))
				{
					int variant = (FishingController.DebugVariant = ((args.Length <= 1 || !args[1].StartsWith("a", StringComparison.OrdinalIgnoreCase)) ? 1 : 2));
					Console.instance.Print("The next ordinary fish to bite comes up " + RareFish.Name(variant).ToLowerInvariant() + ".");
				}
				else if (args[0].Equals("rarefish", StringComparison.OrdinalIgnoreCase))
				{
					Player localPlayer3 = Player.m_localPlayer;
					if ((Object)(object)localPlayer3 == (Object)null || args.Length < 2 || !ContentRegistry.Fish.TryGetValue(args[1], out FishDefinition value2) || !ContentRegistry.FishItems.TryGetValue(value2.Id, out GameObject value3))
					{
						Console.instance.Print("Usage: vdw_debug rarefish <fish id> [golden|albino]");
						return;
					}
					int num3 = ((args.Length <= 2 || !args[2].StartsWith("a", StringComparison.OrdinalIgnoreCase)) ? 1 : 2);
					ItemData val2 = ((Humanoid)localPlayer3).GetInventory().AddItem(((Object)value3).name, 1, 2, num3, 0L, "", false, false);
					if (val2 != null)
					{
						val2.m_customData["vdw_weight_kg"] = ((value2.MinWeightKg + value2.MaxWeightKg) / 2f).ToString("0.00", CultureInfo.InvariantCulture);
					}
					Console.instance.Print((val2 != null) ? ("Gave you a " + RareFish.Name(num3).ToLowerInvariant() + " " + value2.Name + ".") : "No room.");
				}
				else if (args[0].Equals("wear", StringComparison.OrdinalIgnoreCase))
				{
					Player localPlayer4 = Player.m_localPlayer;
					if ((Object)(object)localPlayer4 == (Object)null || args.Length < 2)
					{
						Console.instance.Print("Usage: vdw_debug wear <" + RelicVisuals.WornNames + "> [x|y|z|scale|sx|sy|sz|pitch|yaw|roll] [value | +step | -step | =value]");
						return;
					}
					if (args.Length < 4)
					{
						Console.instance.Print(RelicVisuals.Describe(args[1]));
						return;
					}
					string text4 = args[3];
					bool nudge = text4.StartsWith("+") || text4.StartsWith("-");
					if (text4.StartsWith("="))
					{
						text4 = text4.Substring(1);
					}
					if (!float.TryParse(text4, NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
					{
						Console.instance.Print("Value: a number, +step, -step or =value");
					}
					else
					{
						Console.instance.Print(RelicVisuals.Tune(localPlayer4, args[1], args[2], result3, nudge));
					}
				}
				else if (args[0].Equals("resetrank", StringComparison.OrdinalIgnoreCase))
				{
					if ((Object)(object)Player.m_localPlayer != (Object)null)
					{
						AnglerRanks.Reset(Player.m_localPlayer);
					}
					Console.instance.Print("Rank trophies and weight landed cleared (species and catches still count; resetlog clears those).");
				}
				else if (args[0].Equals("listbait", StringComparison.OrdinalIgnoreCase))
				{
					Console.instance.Print(string.Join(", ", ContentRegistry.Baits.Keys.OrderBy((string x) => x)));
				}
				else if (args[0].Equals("listfish", StringComparison.OrdinalIgnoreCase))
				{
					Console.instance.Print(string.Join(", ", ContentRegistry.Fish.Keys.OrderBy((string x) => x)));
				}
				else if (args[0].Equals("listrods", StringComparison.OrdinalIgnoreCase))
				{
					Console.instance.Print(string.Join(", ", ContentRegistry.Rods.Select((RodDefinition r) => "rod_" + r.Id)));
				}
				else if (args[0].Equals("tokens", StringComparison.OrdinalIgnoreCase))
				{
					string text5 = Path.Combine(Plugin.ConfigDirectory, "translation_template_English.json");
					IEnumerable<string> values = Loc.English.Select<KeyValuePair<string, string>, string>((KeyValuePair<string, string> kv) => "  \"" + kv.Key + "\": \"" + kv.Value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") + "\"");
					File.WriteAllText(text5, "{\n" + string.Join(",\n", values) + "\n}\n");
					Console.instance.Print($"Wrote {Loc.English.Count} tokens to {text5}. Translate the values and save as Translations/<Language>/vdw.json inside the mod's folder in BepInEx/plugins.");
				}
				else if (args[0].Equals("listbuffs", StringComparison.OrdinalIgnoreCase))
				{
					Console.instance.Print(string.Join(", ", from b in FishingBuffs.Buffs.Values
						orderby b.Tier
						select $"buff_{b.Id} ({b.Kind} T{b.Tier})"));
				}
				else if (args[0].Equals("listhooks", StringComparison.OrdinalIgnoreCase))
				{
					Console.instance.Print(string.Join(", ", ContentRegistry.Hooks.Values.Select((HookDefinition h) => $"hook_{h.Id} ({h.MinKg:0.#}-{h.MaxKg:0.#} kg)")));
				}
			}
		}

		public static void Initialize()
		{
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new VdwGiveCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new VdwDebugCommand());
		}
	}
	internal static class ContentRegistry
	{
		public static readonly Dictionary<string, FishDefinition> Fish = new Dictionary<string, FishDefinition>();

		public static readonly Dictionary<string, BaitDefinition> Baits = new Dictionary<string, BaitDefinition>();

		public static readonly Dictionary<string, GameObject> FishItems = new Dictionary<string, GameObject>();

		public static readonly Dictionary<string, GameObject> BaitItems = new Dictionary<string, GameObject>();

		public static readonly Dictionary<string, BaitDefinition> BaitByItemName = new Dictionary<string, BaitDefinition>();

		public static readonly Dictionary<string, HookDefinition> Hooks = new Dictionary<string, HookDefinition>();

		public static readonly Dictionary<string, HookDefinition> HookByItemName = new Dictionary<string, HookDefinition>();

		public static readonly Dictionary<string, TackleDefinition> Tackle = new Dictionary<string, TackleDefinition>();

		public static readonly Dictionary<string, TackleDefinition> TackleByItemName = new Dictionary<string, TackleDefinition>();

		public static readonly List<RodDefinition> Rods = new List<RodDefinition>();

		public static readonly Dictionary<string, RodDefinition> RodByItemName = new Dictionary<string, RodDefinition>();

		private static readonly Dictionary<string, ItemDrop> RodItems = new Dictionary<string, ItemDrop>();

		private static readonly FieldInfo? VisRightHash = AccessTools.Field(typeof(VisEquipment), "m_currentRightItemHash");

		private static readonly (string kind, string id, string oldName)[] RenamedDefaults = new(string, string, string)[3]
		{
			("Baits", "fly", "Feather Fly"),
			("Buffs", "relic_horn", "Horn of Ægir"),
			("Baits", "lure_wyrm", "Wyrm Lure")
		};

		private static readonly (string kind, string id, string oldRecipe)[] UpdatedRecipes = new(string, string, string)[77]
		{
			("Rods", "leviathan", "VDW_BossMat_eikthyr_elver:1,VDW_BossMat_elder_bass:1,VDW_BossMat_bonemass_catfish:1,VDW_BossMat_moder_scale:1,VDW_BossMat_yagluthgill:1,VDW_BossMat_queen_eel:1,YggdrasilWood:10,FlametalNew:6"),
			("Baits", "lure_antler", "TrophyEikthyr:1,HardAntler:1"),
			("Baits", "lure_root", "TrophyTheElder:1,Root:1"),
			("Baits", "lure_ooze", "TrophyBonemass:1,Ooze:2"),
			("Baits", "lure_wyrm", "TrophyDragonQueen:1,FreezeGland:2"),
			("Baits", "lure_ember", "TrophyGoblinKing:1,SurtlingCore:1"),
			("Baits", "lure_chitin", "TrophySeekerQueen:1,Carapace:2"),
			("Buffs", "steady_major", "Honey:2,Cloudberry:4,Eitr:1,VDW_Mat_ink:1"),
			("Buffs", "grip_major", "Honey:2,Barley:4,LoxMeat:1,VDW_Mat_roe:2"),
			("Baits", "lure_feather_fly", "Feathers:2,Resin:1"),
			("Baits", "lure_flint_spinner", "Flint:1,Feathers:1,Wood:1"),
			("Baits", "lure_leather_grub", "LeatherScraps:2,Resin:1"),
			("Baits", "lure_bronze_spoon", "Bronze:1,LeatherScraps:1"),
			("Baits", "lure_finewood_crank", "FineWood:1,Resin:1,BronzeNails:2"),
			("Baits", "lure_guck_crawler", "Guck:1,Resin:2,IronNails:1"),
			("Baits", "lure_bone_jig", "Iron:1,BoneFragments:2,Feathers:1"),
			("Baits", "lure_silver_swimbait", "Silver:1,LeatherScraps:2,FreezeGland:1"),
			("Baits", "lure_linen_popper", "FineWood:1,Feathers:2,LinenThread:1"),
			("Baits", "lure_ice_spoon", "Ice:1,Silver:1"),
			("Baits", "lure_frostcore_jig", "FrostCore:1,Iron:1,BarkaBranch:1"),
			("Baits", "lure_antler", "HardAntler:1,LeatherScraps:2,Flint:1"),
			("Baits", "lure_root", "TrophyTheElder:1,AncientSeed:1,Resin:3"),
			("Baits", "lure_ooze", "TrophyBonemass:1,Ooze:3,WitheredBone:2"),
			("Baits", "lure_wyrm", "DragonTear:2,Silver:1,FreezeGland:1"),
			("Baits", "lure_ember", "YagluthDrop:1,BlackMetal:1,SurtlingCore:1"),
			("Baits", "lure_chitin", "QueenDrop:1,Carapace:2,Eitr:1"),
			("Baits", "lure_crown", "CrownJewel:1,FrostCore:2,Silver:1"),
			("Baits", "deep_bait", "Entrails:1,Ooze:1,Bloodbag:1"),
			("Baits", "frost_bait", "FreezeGland:1,WolfMeat:1"),
			("Baits", "rune_bait", "Silver:1,Eitr:1,SerpentScale:1"),
			("Baits", "northern_bait", "SealBlubber:1,Lingonberry:2"),
			("Buffs", "angler_minor", "Honey:2,Raspberry:4"),
			("Buffs", "angler_medium", "Honey:2,Bloodbag:2,Blueberries:4"),
			("Buffs", "angler_major", "Honey:2,Sap:2,RoyalJelly:1"),
			("Buffs", "angler_north", "Honey:2,Lingonberry:6,Ice:1"),
			("Buffs", "steady_minor", "Honey:2,Thistle:2,Dandelion:2"),
			("Buffs", "steady_medium", "Honey:2,Onion:2,Crystal:1"),
			("Buffs", "steady_major", "Honey:2,Cloudberry:4,Eitr:1"),
			("Buffs", "grip_medium", "Honey:2,WolfFang:2,Onion:2"),
			("Buffs", "grip_major", "Honey:2,Barley:4,LoxMeat:1"),
			("Buffs", "chum_basic", "NeckTail:2,RawMeat:1"),
			("Buffs", "chum_blood", "Bloodbag:2,Entrails:2"),
			("Buffs", "chum_abyssal", "Bloodbag:2,Sap:2,Ooze:2"),
			("Buffs", "chum_blubber", "SealBlubber:2,Lingonberry:4"),
			("Buffs", "rune_njord", "Silver:4,Crystal:2,SerpentScale:2"),
			("Buffs", "totem_fisher", "FineWood:10,ElderBark:4,Guck:2"),
			("Buffs", "totem_njord", "YggdrasilWood:10,Silver:4,Eitr:4"),
			("Baits", "lure_feather_fly", "Feathers:2,Resin:1,VDW_Mat_scales:1"),
			("Baits", "lure_flint_spinner", "Flint:1,Feathers:1,Wood:1,VDW_Mat_scales:1"),
			("Baits", "lure_leather_grub", "LeatherScraps:2,Resin:1,VDW_Mat_oil:1"),
			("Baits", "lure_bronze_spoon", "Bronze:1,LeatherScraps:1,VDW_Mat_scales:2"),
			("Baits", "lure_finewood_crank", "FineWood:1,Resin:1,BronzeNails:2,VDW_Mat_scales:1,GreydwarfEye:1"),
			("Baits", "lure_guck_crawler", "Guck:1,Resin:2,IronNails:1,VDW_Mat_oil:1"),
			("Baits", "lure_bone_jig", "Iron:1,BoneFragments:2,Feathers:1,VDW_Mat_fins:1"),
			("Baits", "lure_silver_swimbait", "Silver:1,LeatherScraps:2,FreezeGland:1,VDW_Mat_fins:1"),
			("Baits", "lure_linen_popper", "FineWood:1,Feathers:2,LinenThread:1,VDW_Mat_roe:1"),
			("Baits", "lure_ice_spoon", "Ice:1,Silver:1,VDW_Mat_rime:1"),
			("Baits", "lure_frostcore_jig", "FrostCore:1,Iron:1,BarkaBranch:1,VDW_Mat_rime:1"),
			("Baits", "lure_antler", "HardAntler:1,LeatherScraps:2,Flint:1,VDW_Mat_scales:2"),
			("Baits", "lure_root", "TrophyTheElder:1,AncientSeed:1,Resin:3,VDW_Mat_scales:3"),
			("Baits", "lure_ooze", "TrophyBonemass:1,Ooze:3,WitheredBone:2,VDW_Mat_oil:3"),
			("Baits", "lure_wyrm", "DragonTear:2,Silver:1,FreezeGland:1,VDW_Mat_fins:3"),
			("Baits", "lure_ember", "YagluthDrop:1,BlackMetal:1,SurtlingCore:1,VDW_Mat_roe:3"),
			("Baits", "lure_chitin", "QueenDrop:1,Carapace:2,Eitr:1,VDW_Mat_ink:3"),
			("Baits", "lure_crown", "CrownJewel:1,FrostCore:2,Silver:1,VDW_Mat_rime:3"),
			("Baits", "lure_feather_fly", "Iron:1,Feathers:3,Resin:2,VDW_Mat_scales:2,VDW_Hook_small:1"),
			("Baits", "lure_feather_fly", "Feathers:3,Resin:2,VDW_Mat_scales:2,VDW_Hook_large:1"),
			("Baits", "lure_flint_spinner", "Iron:1,Flint:2,Feathers:1,VDW_Mat_scales:2,VDW_Hook_small:1"),
			("Baits", "lure_leather_grub", "Iron:1,LeatherScraps:3,Guck:1,VDW_Mat_oil:2,VDW_Hook_small:1"),
			("Baits", "lure_bronze_spoon", "Iron:1,Bronze:2,LeatherScraps:1,VDW_Mat_scales:3,VDW_Hook_medium:1"),
			("Baits", "lure_finewood_crank", "FineWood:2,Resin:2,IronNails:2,GreydwarfEye:2,VDW_Mat_oil:2,VDW_Hook_medium:1"),
			("Baits", "lure_guck_crawler", "Guck:2,Resin:2,IronNails:2,VDW_Mat_oil:2,VDW_Hook_medium:1"),
			("Baits", "lure_bone_jig", "Iron:2,BoneFragments:3,Feathers:1,VDW_Mat_fins:2,VDW_Hook_large:1"),
			("Baits", "lure_silver_swimbait", "Silver:2,LeatherScraps:2,FreezeGland:2,VDW_Mat_fins:2,VDW_Hook_large:1"),
			("Baits", "lure_linen_popper", "FineWood:2,Feathers:2,LinenThread:2,VDW_Mat_roe:2,VDW_Hook_medium:1"),
			("Baits", "lure_ice_spoon", "Ice:1,Silver:2,VDW_Mat_rime:2,VDW_Hook_medium:1"),
			("Baits", "lure_frostcore_jig", "FrostCore:1,Iron:2,BarkaBranch:1,VDW_Mat_rime:2,VDW_Hook_large:1")
		};

		private static readonly (string kind, string id, string field, string oldText)[] UpdatedText = new(string, string, string, string)[1] { ("Buffs", "regalia_njord", "Description", "The four relics of the sea - the Pearl, the Scale, the Horn and the Golden Hook - set in one silver crown. Whoever wears it is the sea god's own angler.") };

		private static readonly (string kind, string id, string field, double oldValue)[] UpdatedStats = new(string, string, string, double)[11]
		{
			("Rods", "copper", "LineCapacity", 40.0),
			("Rods", "finewood", "LineCapacity", 50.0),
			("Rods", "ancientbark", "LineCapacity", 60.0),
			("Rods", "silver", "LineCapacity", 70.0),
			("Rods", "blackmetal", "LineCapacity", 85.0),
			("Rods", "yggdrasil", "LineCapacity", 100.0),
			("Rods", "ashwood", "LineCapacity", 120.0),
			("Rods", "frostwood", "LineCapacity", 135.0),
			("Rods", "haldor", "LineCapacity", 140.0),
			("Rods", "leviathan", "LineCapacity", 160.0),
			("Hooks", "fimbul", "MinKg", 0.0)
		};

		private static readonly (string kind, string field)[] AddedFields = new(string, string)[9]
		{
			("Fish", "Material"),
			("Fish", "FeedMinDepth"),
			("Fish", "FeedMaxDepth"),
			("Fish", "Bottom"),
			("Rods", "Upgrade"),
			("Buffs", "FloatModel"),
			("Buffs", "FloatLight"),
			("Hooks", "HookBonus"),
			("Hooks", "HookWindow")
		};

		private static readonly (string kind, string field, string tag)[] ReplacedFields = new(string, string, string)[8]
		{
			("Baits", "TargetFish", "bait_targets_1"),
			("Fish", "PreferredBaits", "bait_targets_1"),
			("Fish", "PreferredBaits", "bluegill_bait_1"),
			("Fish", "CatchBait", "bluegill_bait_1"),
			("Fish", "CatchAmount", "bluegill_bait_1"),
			("Fish", "ForbiddenBaits", "bluegill_bait_1"),
			("Buffs", "Find", "relics_1"),
			("Hooks", "Find", "relics_1")
		};

		private static readonly (string kind, string id)[] RetiredDefaults = new(string, string)[10]
		{
			("Buffs", "hat_leather"),
			("Buffs", "hat_troll"),
			("Buffs", "hat_seafarer"),
			("Buffs", "cape_seawolf"),
			("Buffs", "cape_netweaver"),
			("Buffs", "cape_ashen"),
			("Fish", "cod"),
			("Fish", "trolltrout"),
			("Fish", "ashscale"),
			("Fish", "dvergr_dace")
		};

		private static readonly Dictionary<string, string> RetiredFishStandIn = new Dictionary<string, string>
		{
			["cod"] = "coral_cod",
			["trolltrout"] = "trollfish",
			["ashscale"] = "magmafish",
			["dvergr_dace"] = "trout"
		};

		public static readonly Dictionary<string, string> FishIdByPrefab = new Dictionary<string, string>();

		private static readonly HashSet<string> VanillaFishingGear = new HashSet<string> { "FishingRod" };

		public static readonly Dictionary<string, GameObject> SwimmingBaitfish = new Dictionary<string, GameObject>();

		private static string OfferedFile => Path.Combine(Plugin.ConfigDirectory, "defaults_offered.dat");

		private static string OldOfferedFile => Path.Combine(Plugin.ConfigDirectory, "defaults_offered.json");

		public static bool IsRod(ItemData? item)
		{
			return GetRod(item) != null;
		}

		public static bool HoldsRod(Player? p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return false;
			}
			if ((Object)(object)p == (Object)(object)Player.m_localPlayer)
			{
				return IsRod(((Humanoid)p).GetCurrentWeapon());
			}
			VisEquipment component = ((Component)p).GetComponent<VisEquipment>();
			if (!((Object)(object)component == (Object)null))
			{
				object obj = VisRightHash?.GetValue(component);
				if (obj is int)
				{
					int held = (int)obj;
					if (held != 0)
					{
						return RodItems.Values.Any((ItemDrop r) => (Object)(object)r != (Object)null && StringExtensionMethods.GetStableHashCode(((Object)((Component)r).gameObject).name) == held);
					}
				}
			}
			return false;
		}

		public static RodDefinition? GetRod(ItemData? item)
		{
			if (item?.m_shared == null || !RodByItemName.TryGetValue(item.m_shared.m_name, out RodDefinition value))
			{
				return null;
			}
			return value;
		}

		public static string RodPrefabName(RodDefinition rod)
		{
			if (Rods.Count <= 0 || rod != Rods[0])
			{
				return "VDW_Rod_" + rod.Id;
			}
			return "VDW_FishingRod";
		}

		public static void Initialize()
		{
			EnsureDataFiles();
			LoadData();
			try
			{
				RegisterRods();
				SetUpHaldor();
				RegisterHooks();
				try
				{
					RegisterTackle();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Weights and leaders failed: {arg}");
				}
				try
				{
					TackleBoxes.Register();
				}
				catch (Exception arg2)
				{
					Plugin.Log.LogError((object)$"Tackle boxes failed: {arg2}");
				}
				FishingBuffs.Register();
				RegisterBaits();
				RegisterFish();
				BossFish.Register();
				try
				{
					FishMaterials.Register();
				}
				catch (Exception arg3)
				{
					Plugin.Log.LogError((object)$"Fish materials failed: {arg3}");
				}
				try
				{
					FishDishes.Register();
				}
				catch (Exception arg4)
				{
					Plugin.Log.LogError((object)$"Fish dishes failed: {arg4}");
				}
				try
				{
					BogWitch.