Decompiled source of Moorings v0.1.2

Moorings.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Moorings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1175ad88add82d49b6326053b3ded7e349e2d302")]
[assembly: AssemblyProduct("Moorings")]
[assembly: AssemblyTitle("Moorings")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Moorings
{
	public static class Mooring
	{
		public static readonly int LinkHash = StringExtensionMethods.GetStableHashCode("Moorings_Link");

		public static readonly int PointHash = StringExtensionMethods.GetStableHashCode("Moorings_Point");

		public static int LinkOf(ZNetView view)
		{
			if (!Object.op_Implicit((Object)(object)view) || !view.IsValid())
			{
				return 0;
			}
			return view.GetZDO().GetInt(LinkHash, 0);
		}

		public static bool IsMoored(ZDO shipZdo)
		{
			if (shipZdo != null)
			{
				return shipZdo.GetInt(LinkHash, 0) != 0;
			}
			return false;
		}

		public static bool IsMoored(Ship ship)
		{
			if (Object.op_Implicit((Object)(object)ship))
			{
				ZNetView component = ((Component)ship).GetComponent<ZNetView>();
				return IsMoored((component != null) ? component.GetZDO() : null);
			}
			return false;
		}

		public static void Tie(ZNetView post, ZNetView ship)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			int num = Random.Range(1, int.MaxValue);
			post.ClaimOwnership();
			ship.ClaimOwnership();
			post.GetZDO().Set(LinkHash, num, false);
			ship.GetZDO().Set(LinkHash, num, false);
			ship.GetZDO().Set(PointHash, ((Component)post).transform.position);
		}

		public static void Release(ZNetView ship)
		{
			if (Object.op_Implicit((Object)(object)ship) && ship.IsValid())
			{
				int link = LinkOf(ship);
				ship.ClaimOwnership();
				ship.GetZDO().Set(LinkHash, 0, false);
				MooringPost mooringPost = FindPost(link);
				if (Object.op_Implicit((Object)(object)mooringPost))
				{
					ZNetView component = ((Component)mooringPost).GetComponent<ZNetView>();
					component.ClaimOwnership();
					component.GetZDO().Set(LinkHash, 0, false);
				}
			}
		}

		public static Ship FindShip(int link)
		{
			if (link == 0)
			{
				return null;
			}
			foreach (IMonoUpdater instance in Ship.Instances)
			{
				Ship val = (Ship)(object)((instance is Ship) ? instance : null);
				if (val != null && LinkOf(((Component)val).GetComponent<ZNetView>()) == link)
				{
					return val;
				}
			}
			return null;
		}

		public static MooringPost FindPost(int link)
		{
			if (link == 0)
			{
				return null;
			}
			foreach (MooringPost item in MooringPost.All)
			{
				if (Object.op_Implicit((Object)(object)item) && LinkOf(((Component)item).GetComponent<ZNetView>()) == link)
				{
					return item;
				}
			}
			return null;
		}

		public static Ship FindNearestShip(Vector3 pos, float range)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Ship result = null;
			float num = range;
			foreach (IMonoUpdater instance in Ship.Instances)
			{
				Ship val = (Ship)(object)((instance is Ship) ? instance : null);
				if (val != null)
				{
					float num2 = Vector3.Distance(((Component)val).transform.position, pos);
					if (num2 < num)
					{
						result = val;
						num = num2;
					}
				}
			}
			return result;
		}
	}
	public class MooringPost : MonoBehaviour, Interactable, Hoverable
	{
		public static readonly List<MooringPost> All = new List<MooringPost>();

		private ZNetView m_nview;

		private LineRenderer m_line;

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			WearNTear component = ((Component)this).GetComponent<WearNTear>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnPostDestroyed));
			}
			All.Add(this);
			MakeCoil();
		}

		private Bounds WorldBounds()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer componentInChildren = ((Component)this).GetComponentInChildren<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				return ((Renderer)componentInChildren).bounds;
			}
			return new Bounds(((Component)this).transform.position + Vector3.up, new Vector3(0.5f, 2f, 0.5f));
		}

		private float PostRadius()
		{
			//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_0009: 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)
			Bounds val = WorldBounds();
			return Mathf.Max(((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).extents.z);
		}

		public float TieHeight()
		{
			//IL_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!(MooringsPlugin.LineHeight.Value >= 0f))
			{
				Bounds val = WorldBounds();
				return ((Bounds)(ref val)).max.y - ((Component)this).transform.position.y - 0.4f;
			}
			return MooringsPlugin.LineHeight.Value;
		}

		private void MakeCoil()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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_0197: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01c1: Expected O, but got Unknown
			GameObject val = new GameObject("coil");
			val.transform.SetParent(((Component)this).transform, false);
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.useWorldSpace = false;
			val2.loop = false;
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
			MeshRenderer componentInChildren = ((Component)this).GetComponentInChildren<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				((Renderer)val2).material = ((Renderer)componentInChildren).sharedMaterial;
			}
			float num = ((MooringsPlugin.CoilRadius.Value > 0f) ? MooringsPlugin.CoilRadius.Value : (PostRadius() + 0.02f));
			float num2 = TieHeight();
			float num3 = 0.055f;
			int num4 = 129;
			float num5 = 8f;
			val2.positionCount = num4;
			for (int i = 0; i < num4; i++)
			{
				float num6 = (float)i / 32f * (float)Math.PI * 2f;
				float num7 = num2 - 4f * num3 / 2f + (float)i / 32f * num3;
				float num8 = (float)Mathf.Min(i, num4 - 1 - i) / num5;
				float num9 = 1f - Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(num8));
				float num10 = num - num9 * 0.05f;
				val2.SetPosition(i, new Vector3(Mathf.Cos(num6) * num10, num7, Mathf.Sin(num6) * num10));
			}
			float num11 = num5 / (float)(num4 - 1);
			val2.widthCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4]
			{
				new Keyframe(0f, 0f),
				new Keyframe(num11, 1f),
				new Keyframe(1f - num11, 1f),
				new Keyframe(1f, 0f)
			});
			val2.widthMultiplier = 0.05f;
		}

		private void OnDestroy()
		{
			All.Remove(this);
		}

		private void OnPostDestroyed()
		{
			Ship mooredShip = GetMooredShip();
			if (Object.op_Implicit((Object)(object)mooredShip))
			{
				Mooring.Release(((Component)mooredShip).GetComponent<ZNetView>());
			}
		}

		private Ship GetMooredShip()
		{
			return Mooring.FindShip(Mooring.LinkOf(m_nview));
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (hold || !m_nview.IsValid())
			{
				return false;
			}
			Ship mooredShip = GetMooredShip();
			if (Object.op_Implicit((Object)(object)mooredShip))
			{
				Mooring.Release(((Component)mooredShip).GetComponent<ZNetView>());
				((Character)user).Message((MessageType)2, "Cast off", 0, (Sprite)null, false);
				return true;
			}
			if (Mooring.LinkOf(m_nview) != 0)
			{
				m_nview.ClaimOwnership();
				m_nview.GetZDO().Set(Mooring.LinkHash, 0, false);
			}
			Ship val = Mooring.FindNearestShip(((Component)this).transform.position, MooringsPlugin.MoorRange.Value);
			if (!Object.op_Implicit((Object)(object)val))
			{
				((Character)user).Message((MessageType)2, "No boat close enough", 0, (Sprite)null, false);
				return false;
			}
			if (Mooring.IsMoored(val))
			{
				((Character)user).Message((MessageType)2, "That boat is already moored", 0, (Sprite)null, false);
				return false;
			}
			Mooring.Tie(m_nview, ((Component)val).GetComponent<ZNetView>());
			((Character)user).Message((MessageType)2, "Moored", 0, (Sprite)null, false);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverName()
		{
			return "Mooring post";
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public string GetHoverText()
		{
			string text = (Object.op_Implicit((Object)(object)GetMooredShip()) ? "Cast off" : "Moor nearest boat");
			return Localization.instance.Localize("Mooring post\n[<color=yellow><b>$KEY_Use</b></color>] " + text);
		}

		private void Update()
		{
			//IL_005b: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			Ship mooredShip = GetMooredShip();
			if (!Object.op_Implicit((Object)(object)mooredShip))
			{
				if (Object.op_Implicit((Object)(object)m_line))
				{
					((Renderer)m_line).enabled = false;
				}
				return;
			}
			if (!Object.op_Implicit((Object)(object)m_line))
			{
				m_line = MakeLine();
			}
			((Renderer)m_line).enabled = true;
			m_line.SetPosition(0, ((Component)this).transform.position + Vector3.up * TieHeight());
			m_line.SetPosition(1, ((Component)mooredShip).transform.position + Vector3.up * 0.5f);
		}

		private LineRenderer MakeLine()
		{
			LineRenderer val = ((Component)this).gameObject.AddComponent<LineRenderer>();
			val.positionCount = 2;
			val.useWorldSpace = true;
			val.startWidth = 0.05f;
			val.endWidth = 0.05f;
			((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
			MeshRenderer componentInChildren = ((Component)this).GetComponentInChildren<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				((Renderer)val).material = ((Renderer)componentInChildren).sharedMaterial;
			}
			return val;
		}
	}
	[BepInPlugin("games.loxley.moorings", "Moorings", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MooringsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "games.loxley.moorings";

		public const string PluginName = "Moorings";

		public const string PluginVersion = "0.1.2";

		public const string PrefabName = "MooringPost";

		public static ConfigEntry<float> MoorRange;

		public static ConfigEntry<float> Slack;

		public static ConfigEntry<float> Pull;

		public static ConfigEntry<float> LineHeight;

		public static ConfigEntry<float> CoilRadius;

		private void Awake()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			MoorRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MoorRange", 12f, "How far (m) a boat can be from the post and still be tied to it.");
			Slack = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Slack", 3f, "How far (m) the nearest end of a moored boat can drift from the post before the line pulls it back. Half the hull length is added automatically.");
			Pull = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Pull", 6f, "Strength of the pull back toward the post once past the slack.");
			LineHeight = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LineHeight", -1f, "How high up the post (m) the line is tied. -1 = just below the top of the post.");
			CoilRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CoilRadius", -1f, "Radius (m) of the rope coiled round the post. -1 = measured from the post.");
			PrefabManager.OnVanillaPrefabsAvailable += AddMooringPost;
			new Harmony("games.loxley.moorings").PatchAll();
		}

		private void AddMooringPost()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			GameObject obj = PrefabManager.Instance.CreateClonedPrefab("MooringPost", "wood_pole_log") ?? PrefabManager.Instance.CreateClonedPrefab("MooringPost", "wood_pole2");
			obj.AddComponent<MooringPost>();
			PieceConfig val = new PieceConfig();
			val.Name = "Mooring post";
			val.Description = "Tie the nearest boat to it. A moored boat cannot be damaged.";
			val.PieceTable = PieceTables.Hammer;
			val.Category = PieceCategories.Misc;
			val.CraftingStation = CraftingStations.Workbench;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Wood", 6, 0, true),
				new RequirementConfig("Resin", 2, 0, true)
			};
			CustomPiece val2 = new CustomPiece(obj, true, val);
			PieceManager.Instance.AddPiece(val2);
			PrefabManager.OnVanillaPrefabsAvailable -= AddMooringPost;
		}
	}
	[HarmonyPatch(typeof(WearNTear), "RPC_Damage")]
	internal static class WearNTear_RPC_Damage_Patch
	{
		private static bool Prefix(WearNTear __instance)
		{
			Ship component = ((Component)__instance).GetComponent<Ship>();
			if (Object.op_Implicit((Object)(object)component))
			{
				return !Mooring.IsMoored(component);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(WearNTear), "ApplyDamage")]
	internal static class WearNTear_ApplyDamage_Patch
	{
		private static bool Prefix(WearNTear __instance, ref bool __result)
		{
			Ship component = ((Component)__instance).GetComponent<Ship>();
			if (Object.op_Implicit((Object)(object)component) && Mooring.IsMoored(component))
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Ship), "CustomFixedUpdate")]
	internal static class Ship_CustomFixedUpdate_Patch
	{
		private static readonly Dictionary<Ship, (float last, int misses)> s_postCheck = new Dictionary<Ship, (float, int)>();

		private static void Postfix(Ship __instance, float fixedDeltaTime)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsOwner())
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (!Mooring.IsMoored(zDO))
			{
				return;
			}
			s_postCheck.TryGetValue(__instance, out (float, int) value);
			if (Time.time - value.Item1 > 2f)
			{
				value.Item1 = Time.time;
				value.Item2 = ((!Object.op_Implicit((Object)(object)Mooring.FindPost(zDO.GetInt(Mooring.LinkHash, 0)))) ? (value.Item2 + 1) : 0);
				s_postCheck[__instance] = value;
				if (value.Item2 >= 5)
				{
					s_postCheck.Remove(__instance);
					Mooring.Release(component);
					return;
				}
			}
			Rigidbody component2 = ((Component)__instance).GetComponent<Rigidbody>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				Vector3 val = zDO.GetVec3(Mooring.PointHash, ((Component)__instance).transform.position) - ((Component)__instance).transform.position;
				val.y = 0f;
				float magnitude = ((Vector3)(ref val)).magnitude;
				float num = (Object.op_Implicit((Object)(object)__instance.m_floatCollider) ? (__instance.m_floatCollider.size.z * ((Component)__instance.m_floatCollider).transform.lossyScale.z * 0.5f) : 3f);
				float num2 = MooringsPlugin.Slack.Value + num;
				if (magnitude > num2)
				{
					component2.AddForce(((Vector3)(ref val)).normalized * (magnitude - num2) * MooringsPlugin.Pull.Value, (ForceMode)5);
				}
				Vector3 linearVelocity = component2.linearVelocity;
				linearVelocity.x *= 0.95f;
				linearVelocity.z *= 0.95f;
				component2.linearVelocity = linearVelocity;
			}
		}
	}
	[HarmonyPatch(typeof(Ship), "Forward")]
	internal static class Ship_Forward_Patch
	{
		private static void Prefix(Ship __instance)
		{
			CastOff(__instance);
		}

		public static void CastOff(Ship ship)
		{
			if (Mooring.IsMoored(ship))
			{
				Mooring.Release(((Component)ship).GetComponent<ZNetView>());
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "Cast off", 0, (Sprite)null, false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Ship), "Backward")]
	internal static class Ship_Backward_Patch
	{
		private static void Prefix(Ship __instance)
		{
			Ship_Forward_Patch.CastOff(__instance);
		}
	}
}