Decompiled source of SailInfo v1.2.1

SailInfo.dll

Decompiled 3 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SailInfo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SailInfo")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2eaa768e-251a-47e7-b1c7-0b5ce52789c9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SailInfo;

public class RudderHUD : MonoBehaviour
{
	private BoatInfo boatInfo;

	private GoPointerButton button;

	public void Awake()
	{
		boatInfo = ((Component)this).gameObject.AddComponent<BoatInfo>();
		button = ((Component)this).GetComponent<GoPointerButton>();
	}

	public void Update()
	{
		if (button.IsLookedAt() || button.IsStickyClicked() || button.IsCliked())
		{
			button.description = boatInfo.RudderHUD();
		}
	}
}
public class SailInfoPatches
{
	public static int winchColorIndex = 0;

	public static Color[] colorArray = (Color[])(object)new Color[9]
	{
		Color.black,
		Color.blue,
		Color.cyan,
		Color.gray,
		Color.green,
		Color.magenta,
		Color.red,
		Color.white,
		Color.yellow
	};

	public static void UpdatePatch(GPButtonRopeWinch __instance, GoPointer ___stickyClickedBy, bool ___isLookedAt, bool ___isClicked)
	{
		if (___isLookedAt || Object.op_Implicit((Object)(object)___stickyClickedBy) || ___isClicked)
		{
			((GoPointerButton)__instance).description = ((Component)__instance.rope).GetComponent<WinchInfo>()?.WinchHUD();
		}
	}

	public static void CapstanPatch(RopeControllerAnchor __instance)
	{
		((Component)__instance).gameObject.AddComponent<WinchInfo>();
	}

	public static void RudderPatch(Rudder __instance)
	{
		BoatHorizon componentInParent = ((Component)__instance).GetComponentInParent<BoatHorizon>();
		Transform val = ((componentInParent != null) ? ((Component)componentInParent).transform : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform val2;
		Transform val3;
		if (((Object)val).name == "cutterModel")
		{
			val2 = ((Component)__instance).transform.Find("rudder_tiller_cutter");
			val3 = ((Component)__instance).transform.Find("rudder_tiller_cutter_center");
		}
		else
		{
			if (!(((Object)val).name == "paraw"))
			{
				GPButtonSteeringWheel[] componentsInChildren = ((Component)val).GetComponentsInChildren<GPButtonSteeringWheel>();
				GPButtonSteeringWheel[] array = componentsInChildren;
				foreach (GPButtonSteeringWheel val4 in array)
				{
					((Component)val4).gameObject.AddComponent<RudderHUD>();
				}
				return;
			}
			val2 = val.Find("hull_regular").Find("rudder_right_reg").Find("tiller_reg");
			val3 = val.Find("hull_extension").Find("rudder_right_ext").Find("tiller_ext");
		}
		((Component)val2).gameObject.AddComponent<RudderHUD>();
		((Component)val3).gameObject.AddComponent<RudderHUD>();
	}

	public static string SailName(Sail currentSail, SailNameType nameType)
	{
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Invalid comparison between Unknown and I4
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Invalid comparison between Unknown and I4
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Invalid comparison between Unknown and I4
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Invalid comparison between Unknown and I4
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Invalid comparison between Unknown and I4
		string[] array = new string[6] { "Course", "Topsail", "T'gallant", "Royal", "Skysail", "Moonraker" };
		string[] array2 = new string[6] { "Bottom Square", "Lower Square", "Middle Square", "Upper Square", "Top Square", "Highest Square" };
		Mast component = ((Component)((Component)currentSail).transform.parent).GetComponent<Mast>();
		if (currentSail.squareSail)
		{
			if (component.onlySquareSails && nameType == SailNameType.Historical)
			{
				if (Object.op_Implicit((Object)(object)((Component)currentSail).GetComponent<SquareTopsailAngleMirror>()))
				{
					return "Sprit Topsail";
				}
				return "Spritsail";
			}
			string[] array3 = ((nameType == SailNameType.Historical) ? array : array2);
			int num = 0;
			SquareTopsailAngleMirror val = ((Component)currentSail).GetComponent<SquareTopsailAngleMirror>();
			num = 0;
			while (num < array3.Length && !((Object)(object)val == (Object)null))
			{
				component = ((Component)((Component)val.sailBelow).transform.parent).GetComponent<Mast>();
				num++;
				val = ((Component)val.sailBelow).GetComponent<SquareTopsailAngleMirror>() ?? null;
			}
			return MastName(component) + array3[num];
		}
		if ((int)currentSail.category == 3)
		{
			return MastName(component) + "Gaff";
		}
		if ((int)currentSail.category == 1)
		{
			return MastName(component) + "Lateen";
		}
		if ((int)currentSail.category == 2)
		{
			return MastName(component) + "Junk";
		}
		if ((int)currentSail.category == 4)
		{
			if (((Object)currentSail).name.Contains("junklateen"))
			{
				return MastName(component) + "Fin";
			}
			if (((Object)currentSail).name.Contains("lug"))
			{
				return MastName(component) + "Lug";
			}
			if (((Object)currentSail).name.Contains("tanja"))
			{
				return MastName(component) + "Tanja";
			}
		}
		if ((int)currentSail.category == 5)
		{
			if (MastName(component) == "Forestay ")
			{
				if (((Object)currentSail).name.Contains("genoa"))
				{
					return "Genoa";
				}
				return "Jib";
			}
			return MastName(component) + "Staysail";
		}
		return "";
	}

	public static string MastName(Mast currentMast)
	{
		string text = ((Component)currentMast).GetComponent<BoatPartOption>()?.optionName ?? "";
		if (currentMast.onlyStaysails)
		{
			if (text.ToLower().Contains("forestay"))
			{
				return "Forestay ";
			}
			foreach (BoatPartOption require in ((Component)currentMast).GetComponent<BoatPartOption>().requires)
			{
				if (require.optionName.ToLower().Contains("mizzen"))
				{
					return "Mizzen ";
				}
			}
		}
		Mast[] componentsInChildren = ((Component)GameState.currentBoat).GetComponentsInChildren<Mast>();
		int num = componentsInChildren.Length;
		for (int i = 0; i < num; i++)
		{
			if (componentsInChildren[i].onlyStaysails || componentsInChildren[i].onlySquareSails)
			{
				num--;
			}
		}
		if (num > 1)
		{
			if (((Object)currentMast).name.Contains("bowsprit"))
			{
				return "Bowsprit ";
			}
			if (text.ToLower().Contains("foremast"))
			{
				return "Foremast ";
			}
			if (text.ToLower().Contains("main") || ((Object)currentMast).name == "mast" || ((Object)currentMast).name == "mast_1" || ((Object)currentMast).name == "mast_0_extension" || ((Object)currentMast).name == "mast_1_extension" || ((Object)currentMast).name == "mast_center" || ((Object)currentMast).name == "mast_mid_0" || ((Object)currentMast).name == "mast_mid_1" || ((Object)currentMast).name == "mast_front" || ((Object)currentMast).name == "mast_Back_1" || ((Object)currentMast).name == "mast_Back_2")
			{
				if (text.ToLower().Contains("topmast"))
				{
					return "Main Topmast ";
				}
				return "Mainmast ";
			}
			if (text.ToLower().Contains("mizzen"))
			{
				if (text.ToLower().Contains("topmast"))
				{
					return "Mizzen Topmast ";
				}
				return "Mizzen ";
			}
		}
		return "";
	}

	private static void WinchColor(GPButtonRopeWinch winch, int winchColorIndex)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		winchColorIndex %= colorArray.Length;
		((Renderer)((Component)((Component)winch).transform).GetComponent<MeshRenderer>()).material.color = colorArray[winchColorIndex];
	}

	public static void ClockPatch(ShipItemClock __instance, bool ___isLookedAt)
	{
		if (!___isLookedAt)
		{
			return;
		}
		((GoPointerButton)__instance).description = "";
		if (SailInfoMain.showGlobalTimeConfig.Value || SailInfoMain.showLocalTimeConfig.Value)
		{
			if (SailInfoMain.showGlobalTimeConfig.Value)
			{
				float globalTime = Sun.sun.globalTime;
				((GoPointerButton)__instance).description = ((GoPointerButton)__instance).description + "\n\n" + GetTime(globalTime);
			}
			if (SailInfoMain.showLocalTimeConfig.Value)
			{
				float localTime = Sun.sun.localTime;
				((GoPointerButton)__instance).description = ((GoPointerButton)__instance).description + "\n" + GetTime(localTime);
			}
		}
	}

	private static string GetTime(float time)
	{
		int num = (int)time;
		int num2 = (int)((time - (float)num) * 60f);
		if (num2 < 10)
		{
			return $"{num}:0{num2}";
		}
		return $"{num}:{num2}";
	}

	public static void AwakePatch(Sail ___sail, RopeController ___reefController, RopeController ___angleControllerMid, RopeController ___angleControllerLeft, RopeController ___angleControllerRight)
	{
		if ((Object)(object)___angleControllerMid != (Object)null || ((Object)(object)___angleControllerLeft != (Object)null && (Object)(object)___angleControllerRight != (Object)null))
		{
			if ((Object)(object)___angleControllerMid != (Object)null)
			{
				WinchInfoSail winchInfoSail = ((Component)___angleControllerMid).gameObject.GetComponent<WinchInfoSail>() ?? ((Component)___angleControllerMid).gameObject.AddComponent<WinchInfoSail>();
				winchInfoSail.sailComponent = ___sail;
			}
			if ((Object)(object)___angleControllerLeft != (Object)null && (Object)(object)___angleControllerRight != (Object)null)
			{
				WinchInfoSail winchInfoSail2 = ((Component)___angleControllerLeft).gameObject.GetComponent<WinchInfoSail>() ?? ((Component)___angleControllerLeft).gameObject.AddComponent<WinchInfoSail>();
				winchInfoSail2.sailComponent = ___sail;
				WinchInfoSail winchInfoSail3 = ((Component)___angleControllerRight).gameObject.GetComponent<WinchInfoSail>() ?? ((Component)___angleControllerRight).gameObject.AddComponent<WinchInfoSail>();
				winchInfoSail3.sailComponent = ___sail;
			}
			WinchInfoSail winchInfoSail4 = ((Component)___reefController).gameObject.GetComponent<WinchInfoSail>() ?? ((Component)___reefController).gameObject.AddComponent<WinchInfoSail>();
			winchInfoSail4.sailComponent = ___sail;
		}
	}

	public static void UpdateControllerAttachmentsPatch(Mast __instance)
	{
		if (!GameState.currentlyLoading)
		{
			return;
		}
		GPButtonRopeWinch[] leftAngleWinch = __instance.leftAngleWinch;
		GPButtonRopeWinch[] rightAngleWinch = __instance.rightAngleWinch;
		GPButtonRopeWinch[] midAngleWinch = __instance.midAngleWinch;
		GPButtonRopeWinch[] reefWinch = __instance.reefWinch;
		foreach (GameObject sail in __instance.sails)
		{
			Sail component = sail.GetComponent<Sail>();
			SailConnections component2 = sail.GetComponent<SailConnections>();
			bool flag = false;
			if (component.squareSail)
			{
				for (int num = component.mastOrder - 1; num >= 0; num--)
				{
					if ((Object)(object)__instance.sails[num] != (Object)null && __instance.sails[num].GetComponent<Sail>().squareSail)
					{
						flag = true;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)component2.reefController))
			{
				WinchColor(reefWinch[component.mastOrder], winchColorIndex);
			}
			if (Object.op_Implicit((Object)(object)component2.angleControllerMid))
			{
				WinchColor(midAngleWinch[component.mastOrder], winchColorIndex);
			}
			if (Object.op_Implicit((Object)(object)component2.angleControllerLeft) || Object.op_Implicit((Object)(object)component2.angleControllerRight))
			{
				if (component.squareSail)
				{
					if (!flag)
					{
						WinchColor(leftAngleWinch[0], winchColorIndex);
						WinchColor(rightAngleWinch[0], winchColorIndex);
					}
				}
				else
				{
					WinchColor(leftAngleWinch[component.mastOrder], winchColorIndex);
					WinchColor(rightAngleWinch[component.mastOrder], winchColorIndex);
				}
			}
			winchColorIndex++;
		}
	}

	private static Component GetComponentByString(GameObject obj, string component)
	{
		return obj.GetComponent(component);
	}
}
public class WinchInfo : MonoBehaviour
{
	protected RopeController rope;

	public virtual void Awake()
	{
		rope = ((Component)this).GetComponent<RopeController>();
	}

	protected StringBuilder Bar(float amount)
	{
		StringBuilder stringBuilder = new StringBuilder();
		int num = 300;
		int num2 = (int)(amount * (float)num);
		for (int i = 0; i < num; i++)
		{
			if (i < num2)
			{
				stringBuilder.Append("█");
			}
			else
			{
				stringBuilder.Append("░");
			}
		}
		return stringBuilder;
	}

	private float AnchorAngle()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: 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_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)
		float result = 0f;
		RopeController obj = rope;
		RopeControllerAnchor val = (RopeControllerAnchor)(object)((obj is RopeControllerAnchor) ? obj : null);
		if (val != null)
		{
			ConfigurableJoint joint = val.joint;
			Vector3 position = ((Component)joint).transform.position;
			Vector3 val2 = ((Component)((Joint)joint).connectedBody).transform.TransformPoint(((Joint)joint).connectedAnchor);
			result = Vector3.Angle(val2 - position, Vector3.up);
		}
		return result;
	}

	public virtual string WinchHUD()
	{
		float currentLength = rope.currentLength;
		string text = "";
		RopeController obj = rope;
		RopeControllerAnchor val = (RopeControllerAnchor)(object)((obj is RopeControllerAnchor) ? obj : null);
		if (val != null)
		{
			float num = currentLength * val.maxLength;
			if (num > 0.05f)
			{
				if (SailInfoMain.winchesAnchorAngleConfig.Value == ColorCoding.ColorCoded)
				{
					float num2 = AnchorAngle();
					text = ((!(num2 > 50f)) ? (text + $"<color=#7C0000>{Mathf.Round(num2)}°</color>") : (text + $"<color=#113905>{Mathf.Round(num2)}°</color>"));
				}
				else if (SailInfoMain.winchesAnchorAngleConfig.Value == ColorCoding.Plain)
				{
					text += $"{Mathf.Round(AnchorAngle())}°";
				}
			}
			if (SailInfoMain.winchesOutConfig2.Value == WinchOutTypeLinear.Absolute)
			{
				text += $"<size=70%>\n{Mathf.Round(num)} yds out</size>";
			}
			else if (SailInfoMain.winchesOutConfig2.Value == WinchOutTypeLinear.Percent)
			{
				text += $"<size=70%>\n{Mathf.Round(currentLength * 100f)}% out</size>";
			}
		}
		if (SailInfoMain.winchesBarConfig.Value)
		{
			text += $"\n<size=3%>{Bar(currentLength)}</size>";
		}
		return text;
	}
}
internal class BoatInfo : MonoBehaviour
{
	private Transform boat;

	private Rigidbody shipRigidbody;

	private HingeJoint rudderJoint;

	private Rudder rudder;

	public void Awake()
	{
		boat = ((Component)((Component)this).GetComponentInParent<PurchasableBoat>()).transform;
		shipRigidbody = ((Component)boat).GetComponent<Rigidbody>();
		rudder = ((Component)boat).GetComponentInChildren<Rudder>();
		rudderJoint = ((Component)rudder).GetComponent<HingeJoint>();
	}

	public string RudderHUD()
	{
		//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
		string text = "";
		if (SailInfoMain.windSpeedConfig.Value > WindSpeedType.None || SailInfoMain.windDirectionConfig.Value > HeadingType.None || SailInfoMain.windRelativeConfig.Value > ColorCoding.None)
		{
			text = "Wind: ";
		}
		if (SailInfoMain.windSpeedConfig.Value == WindSpeedType.Beaufort)
		{
			text = text + Beaufort() + " ";
		}
		else if (SailInfoMain.windSpeedConfig.Value == WindSpeedType.Knots)
		{
			text += $"{Mathf.Round(WindForce())} kts ";
		}
		if (SailInfoMain.windDirectionConfig.Value == HeadingType.Cardinal)
		{
			text = text + DirectionNESW(Mathf.Round(WindDirection())) + " ";
		}
		else if (SailInfoMain.windDirectionConfig.Value == HeadingType.Degrees)
		{
			text += $"{Mathf.Round(WindDirection())}° ";
		}
		if (SailInfoMain.windRelativeConfig.Value == ColorCoding.ColorCoded)
		{
			float num = AngleToBoat();
			text = ((!(num > 0f)) ? (text + $"<color=#7C0000>{Mathf.Round(num)}°</color>") : (text + $"<color=#113905>{Mathf.Round(num)}°</color>"));
		}
		else if (SailInfoMain.windRelativeConfig.Value == ColorCoding.Plain)
		{
			text += $"{Mathf.Round(AngleToBoat())}°";
		}
		if (SailInfoMain.boatHeadingConfig.Value != 0 || SailInfoMain.boatSpeedConfig.Value != 0 || SailInfoMain.boatVMGConfig.Value)
		{
			text += "\n";
		}
		if (SailInfoMain.boatSpeedConfig.Value == SpeedUnits.NauticalMilesPerHour)
		{
			float num2 = 80.36f * Sun.sun.initialTimescale;
			text += $"SPD: {Mathf.Round(BoatSpeed() * num2)} nmi/h ";
		}
		else if (SailInfoMain.boatSpeedConfig.Value == SpeedUnits.Standard)
		{
			text += $"SPD: {Mathf.Round(BoatSpeed())} kts ";
		}
		if (SailInfoMain.boatHeadingConfig.Value == HeadingType.Cardinal)
		{
			text = text + "HDG: " + DirectionNESW(Mathf.Round(BoatHeading())) + " ";
		}
		else if (SailInfoMain.boatHeadingConfig.Value == HeadingType.Degrees)
		{
			text += $"HDG: {Mathf.Round(BoatHeading())}° ";
		}
		if (SailInfoMain.boatVMGConfig.Value)
		{
			text += $"VMG: {Mathf.Round(VMG())} kts";
		}
		if (SailInfoMain.boatHeelingConfig.Value)
		{
			text += $"\nHeeling {Mathf.Round(Heeling())}°";
		}
		if (SailInfoMain.showCoordinatesConfig.Value != 0)
		{
			text = text + "\n" + Latitude() + ", " + Longitude();
		}
		if (SailInfoMain.rudderBarConfig.Value)
		{
			string text2 = text;
			float currentAngle = rudder.currentAngle;
			JointLimits limits = rudderJoint.limits;
			text = text2 + "\n" + RudderBar(currentAngle, ((JointLimits)(ref limits)).max);
		}
		return text;
	}

	private string RudderBar(float currentAngle, float angleLimit)
	{
		int num = 150;
		bool flag = currentAngle <= 0f;
		string text = "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░";
		int num2 = (int)(Math.Abs(currentAngle) * (float)num / angleLimit);
		int num3 = num - num2;
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < num; i++)
		{
			if (i < num2)
			{
				stringBuilder.Append("█");
			}
			else
			{
				stringBuilder.Append("░");
			}
		}
		StringBuilder stringBuilder2 = new StringBuilder();
		for (int j = 0; j < num; j++)
		{
			if (j < num3)
			{
				stringBuilder2.Append("░");
			}
			else
			{
				stringBuilder2.Append("█");
			}
		}
		if (flag)
		{
			return $"<size=3%>{text}█{stringBuilder}</size>";
		}
		return $"<size=3%>{stringBuilder2}█{text}</size>";
	}

	private float WindForce()
	{
		//IL_0002: 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)
		Vector3 apparentWind = GetApparentWind();
		return ((Vector3)(ref apparentWind)).magnitude;
	}

	private Vector3 GetApparentWind()
	{
		//IL_0001: 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_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_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		return Wind.currentWind - shipRigidbody.velocity;
	}

	private float WindDirection()
	{
		//IL_0002: 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_0016: Unknown result type (might be due to invalid IL or missing references)
		float num = Vector3.SignedAngle(GetApparentWind(), -Vector3.forward, -Vector3.up);
		return (num < 0f) ? (num + 360f) : num;
	}

	private float BoatHeading()
	{
		//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_0016: Unknown result type (might be due to invalid IL or missing references)
		float num = Vector3.SignedAngle(boat.forward, Vector3.forward, -Vector3.up);
		return (num < 0f) ? (num + 360f) : num;
	}

	private float AngleToBoat()
	{
		//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_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)
		return Vector3.SignedAngle(-boat.forward, GetApparentWind(), Vector3.up);
	}

	private float BoatSpeed()
	{
		//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)
		Vector3 velocity = shipRigidbody.velocity;
		return ((Vector3)(ref velocity)).magnitude * 1.94384f;
	}

	private static string DirectionNESW(float direction)
	{
		string[] array = new string[17]
		{
			"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW",
			"SW", "WSW", "W", "WNW", "NW", "NNW", "N"
		};
		return array[(int)Math.Floor(((double)direction + 11.25) % 360.0 / 22.5)];
	}

	private float VMG()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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)
		Vector3 velocity = shipRigidbody.velocity;
		Vector3 currentWind = Wind.currentWind;
		float num = Vector3.Angle(velocity, currentWind) * ((float)Math.PI / 180f);
		return (0f - BoatSpeed()) * Mathf.Cos(num);
	}

	private static string Beaufort()
	{
		//IL_0001: 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_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Wind.currentWind - ((Component)GameState.currentBoat.parent).GetComponent<Rigidbody>().velocity;
		float magnitude = ((Vector3)(ref val)).magnitude;
		string text = ((magnitude < 1f) ? "Calm(0) " : ((magnitude >= 1f && magnitude < 3f) ? "Light Air(1) " : ((magnitude >= 3f && magnitude < 6f) ? "Light Breeze(2) " : ((magnitude >= 6f && magnitude < 10f) ? "Gentle Breeze(3) " : ((magnitude >= 10f && magnitude < 16f) ? "Moderate Breeze(4) " : ((magnitude >= 16f && magnitude < 21f) ? "Fresh Breeze(5) " : ((magnitude >= 21f && magnitude < 27f) ? "Strong Breeze(6) " : ((magnitude >= 27f && magnitude < 33f) ? "High Wind(7) " : ((magnitude >= 33f && magnitude < 40f) ? "Gale(8) " : ((magnitude >= 40f && magnitude < 47f) ? "Strong Gale(9) " : ((magnitude >= 47f && magnitude < 55f) ? "Storm(10) " : ((magnitude >= 55f && magnitude < 63f) ? "Violent Storm(11) " : ((magnitude >= 63f) ? "Hurricane-force(12) " : "Unknown")))))))))))));
		return "<size=60%>" + text + "</size>";
	}

	private float Heeling()
	{
		//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_0016: Unknown result type (might be due to invalid IL or missing references)
		return Vector3.SignedAngle(boat.up, Vector3.up, -Vector3.forward);
	}

	internal string Latitude()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		float z = FloatingOriginManager.instance.GetGlobeCoords(boat).z;
		if (SailInfoMain.showCoordinatesConfig.Value == CoordinateType.Decimal)
		{
			return $"Lat: {Math.Round(z, 2)}°";
		}
		string arg = ((z < 0f) ? "S" : "N");
		z = Math.Abs(z);
		int num = (int)z;
		int num2 = (int)((z - (float)num) * 60f);
		return $"{num}° {num2}'{arg}";
	}

	internal string Longitude()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		float x = FloatingOriginManager.instance.GetGlobeCoords(boat).x;
		if (SailInfoMain.showCoordinatesConfig.Value == CoordinateType.Decimal)
		{
			return $"Long: {Math.Round(x, 2)}°";
		}
		string arg = ((x < 0f) ? "W" : "E");
		x = Math.Abs(x);
		int num = (int)x;
		int num2 = (int)((x - (float)num) * 60f);
		return $"{num}° {num2}'{arg}";
	}
}
public enum SailNameType
{
	None,
	Standard,
	Historical,
	SimplePositional
}
public enum SpeedUnits
{
	None,
	Standard,
	NauticalMilesPerHour
}
public enum HeadingType
{
	None,
	Cardinal,
	Degrees
}
public enum WindSpeedType
{
	None,
	Beaufort,
	Knots
}
public enum WinchOutType
{
	None,
	Degrees,
	Percent
}
public enum ColorCoding
{
	None,
	Plain,
	ColorCoded
}
public enum CoordinateType
{
	None,
	DegreesAndMinutes,
	Decimal
}
public enum WinchOutTypeLinear
{
	None,
	Absolute,
	Percent
}
[BepInPlugin("pr0skynesis.sailinfo", "SailInfo", "1.2.1")]
public class SailInfoMain : BaseUnityPlugin
{
	public const string pluginGuid = "pr0skynesis.sailinfo";

	public const string pluginName = "SailInfo";

	public const string pluginVersion = "1.2.1";

	public static ConfigEntry<bool> winchesInfoConfig;

	public static ConfigEntry<bool> rudderHUDConfig;

	public static ConfigEntry<ColorCoding> winchesAnchorAngleConfig;

	public static ConfigEntry<WinchOutType> winchesOutConfig;

	public static ConfigEntry<WinchOutTypeLinear> winchesOutConfig2;

	public static ConfigEntry<bool> winchesBarConfig;

	public static ConfigEntry<bool> sailEfficiencyConfig;

	public static ConfigEntry<bool> sailForwardForceConfig;

	public static ConfigEntry<bool> sailSidewaysForceConfig;

	public static ConfigEntry<bool> flipWinchesOutConfig;

	public static ConfigEntry<SailNameType> sailNameConfig;

	public static ConfigEntry<bool> coloredWinchesConfig;

	public static ConfigEntry<bool> rudderBarConfig;

	public static ConfigEntry<WindSpeedType> windSpeedConfig;

	public static ConfigEntry<HeadingType> windDirectionConfig;

	public static ConfigEntry<ColorCoding> windRelativeConfig;

	public static ConfigEntry<HeadingType> boatHeadingConfig;

	public static ConfigEntry<SpeedUnits> boatSpeedConfig;

	public static ConfigEntry<bool> boatVMGConfig;

	public static ConfigEntry<bool> boatHeelingConfig;

	public static ConfigEntry<CoordinateType> showCoordinatesConfig;

	public static ConfigEntry<bool> showGlobalTimeConfig;

	public static ConfigEntry<bool> showLocalTimeConfig;

	public void Awake()
	{
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Expected O, but got Unknown
		//IL_041f: Unknown result type (might be due to invalid IL or missing references)
		//IL_042d: Expected O, but got Unknown
		//IL_0431: Unknown result type (might be due to invalid IL or missing references)
		//IL_043f: Expected O, but got Unknown
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		//IL_0453: Expected O, but got Unknown
		//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b3: Expected O, but got Unknown
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_049e: Expected O, but got Unknown
		//IL_046a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0478: Expected O, but got Unknown
		winchesInfoConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("A) Main Switches", "winchesInfo", true, "Enables or disables the winches information entirely. Requires restarting the game.");
		rudderHUDConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("A) Main Switches", "rudderHUD", true, "Enables or disables the rudder HUD entirely. Requires restarting the game.");
		winchesOutConfig = ((BaseUnityPlugin)this).Config.Bind<WinchOutType>("B) Winches Display: 1. Sail Trimming and Efficiency", "winchesOutText", WinchOutType.Degrees, "Shows 'X out' when looking at winches.\nPercent: 0 means the winch is fully tightened in, 100 means it's fully released.\nReplaces the 'X out' text with the degrees the sail is out, e.g. '45° out'.");
		winchesBarConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Winches Display: 1. Sail Trimming and Efficiency", "winchesBar", true, "Shows a loading bar type of thing when looking at winches. Empty bar means the winch is fully tightened in, 100 means it's fully released. Set to false to disable.");
		sailEfficiencyConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Winches Display: 1. Sail Trimming and Efficiency", "sailEfficiency", true, "Shows the efficiency of the sail attached to the winch you are looking at. Does not apply to halyard winches. Negative means sail is pushing backwards. Maximize to find the best trim. Set to false to disable.");
		sailForwardForceConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Winches Display: 1. Sail Trimming and Efficiency", "sailForwardForce", false, "Shows how close the FORWARD force generated by the sail is to the maximum. 0% means no force forward, 100% means maximum force forward. Maximize for best result. This was called Sail Efficiency up to v1.1.8. Set to true to enable.");
		sailSidewaysForceConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Winches Display: 1. Sail Trimming and Efficiency", "sailSidewayForce", false, "Shows how close the SIDEWAYS force generated by the sail is to the maximum. 0% means no force sideway, 100% means maximum force sideway. Minimize for best result. Set to true to enable.");
		flipWinchesOutConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Winches Display: 1. Sail Trimming and Efficiency", "flipWinchesOut", true, "Flips the 'X out' when looking at halyard winches of sail that folds by releasing the rope, like junk sails and some gaffs. When true the sail will be at 100 out when fully opened and at 0 when close, making it more consistent with other type of sail.");
		sailNameConfig = ((BaseUnityPlugin)this).Config.Bind<SailNameType>("B) Winches Display: 2. Sail Names", "sailName", SailNameType.None, "Shows the name of the sail attached to the winch currently looked at.\nStandard: Exact sail name (e.g. \"brig square 9yd\").\nHistorical: Traditional names based on mast and position (e.g. \"Mizzen T'Gallant\").\nSimple Positional: Uses simple prefixes for sail names (Bottom, Middle, Top, Highest) followed by sail type (Square, Gaff, Lateen, etc.).");
		coloredWinchesConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Winches Display: 2. Sail Names", "coloredWinches", false, "Colors all the winches attached to a single sail of the same color, making it easier to identify. Change to true to enable.");
		winchesAnchorAngleConfig = ((BaseUnityPlugin)this).Config.Bind<ColorCoding>("B) Winches Display: 3. Anchor Information", "anchorAngle", ColorCoding.ColorCoded, "Shows angle between anchor and pulley when looking at winch. Set to false to disable.");
		winchesOutConfig2 = ((BaseUnityPlugin)this).Config.Bind<WinchOutTypeLinear>("B) Winches Display: 3. Anchor Information", "anchorOutText", WinchOutTypeLinear.Absolute, "Shows 'X out' when looking at winches.\nPercent: 0 means the winch is fully tightened in, 100 means it's fully released.\nReplaces the 'X out' text with the amount of rope out, e.g. '45 yds out'.");
		rudderBarConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("C) Rudder HUD: 5. Other", "rudderBar", true, "Shows a loading bar type of thing indicating how much the rudder is turned either way.  Set to false to disable.");
		windSpeedConfig = ((BaseUnityPlugin)this).Config.Bind<WindSpeedType>("C) Rudder HUD: 1. Apparent Wind", "windSpeed", WindSpeedType.Beaufort, "Shows the APPARENT wind speed.\nKnots: Wind speed in knots.\nBeaufort: Descriptor words (e.g. Calm, Light Breeze, Gale, etc.");
		windDirectionConfig = ((BaseUnityPlugin)this).Config.Bind<HeadingType>("C) Rudder HUD: 1. Apparent Wind", "windDirection", HeadingType.Cardinal, "Shows APPARENT wind direction in degree, relative to the world (e.g. 45° means the APPARENT wind comes from the North-West).\nDegrees: show precise wind direction in degrees.\nCardinal: Approximate cardinal direction (e.g. wind coming from 45° will be shown as NW instead of it's exact numerical value.");
		windRelativeConfig = ((BaseUnityPlugin)this).Config.Bind<ColorCoding>("C) Rudder HUD: 2. Point of Sail", "windAngleToBoat", ColorCoding.ColorCoded, "Shows the angle (0°-180°) between the APPARENT wind and the boat forward direction. Negative angles mean the wind comes from the left of the boat.\nPlain: White text\nColor Coded: Green if wind comes from the right, red if wind comes from the left.");
		boatHeadingConfig = ((BaseUnityPlugin)this).Config.Bind<HeadingType>("C) Rudder HUD: 3. Heading", "boatHeading", HeadingType.Cardinal, "Shows the boat heading.\nDegrees: Heading in degrees.\nCardinal: Approximate boat heading in cardinal directions (e.g. N, NW, SSE, etc.).");
		boatSpeedConfig = ((BaseUnityPlugin)this).Config.Bind<SpeedUnits>("C) Rudder HUD: 4. Boat Speed", "boatSpeed", SpeedUnits.None, "Shows current boat speed.\nKnots: speed in chiplog knots.\nNautical Miles Per Hour: speed in nautical miles per hour instead of kts. In the game nmi/h = kts / 1.555.");
		boatVMGConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("C) Rudder HUD: 4. Boat Speed", "boatVMG", false, "Shows the current boat VMG in kts. Set to false to disable.");
		boatHeelingConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("C) Rudder HUD: 5. Other", "boatHeeling", false, "Shows current boat heeling in degrees.");
		showCoordinatesConfig = ((BaseUnityPlugin)this).Config.Bind<CoordinateType>("C) Rudder HUD: 5. Other", "showCoordinates", CoordinateType.None, "Adds latitude and longitude to the rudder HUD. Set to true to enable.");
		showGlobalTimeConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("D) Other Items: 1. Clock", "showGlobalTime", false, "Shows exact global time in the hh:mm format when looking at a clock. Set to true to enable.");
		showLocalTimeConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("D) Other Items: 1. Clock", "showLocalTime", false, "Shows exact local time in the hh:mm format when looking at a clock. Set to true to enable.");
		Harmony val = new Harmony("pr0skynesis.sailinfo");
		MethodInfo methodInfo = AccessTools.Method(typeof(GPButtonRopeWinch), "Update", (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(SailInfoPatches), "UpdatePatch", (Type[])null, (Type[])null);
		MethodInfo methodInfo3 = AccessTools.Method(typeof(Rudder), "Start", (Type[])null, (Type[])null);
		MethodInfo methodInfo4 = AccessTools.Method(typeof(SailInfoPatches), "RudderPatch", (Type[])null, (Type[])null);
		MethodInfo methodInfo5 = AccessTools.Method(typeof(SailConnections), "Awake", (Type[])null, (Type[])null);
		MethodInfo methodInfo6 = AccessTools.Method(typeof(SailInfoPatches), "AwakePatch", (Type[])null, (Type[])null);
		MethodInfo methodInfo7 = AccessTools.Method(typeof(Mast), "UpdateControllerAttachments", (Type[])null, (Type[])null);
		MethodInfo methodInfo8 = AccessTools.Method(typeof(SailInfoPatches), "UpdateControllerAttachmentsPatch", (Type[])null, (Type[])null);
		MethodInfo methodInfo9 = AccessTools.Method(typeof(ShipItemClock), "ExtraLateUpdate", (Type[])null, (Type[])null);
		MethodInfo methodInfo10 = AccessTools.Method(typeof(SailInfoPatches), "ClockPatch", (Type[])null, (Type[])null);
		MethodInfo methodInfo11 = AccessTools.Method(typeof(RopeControllerAnchor), "Start", (Type[])null, (Type[])null);
		MethodInfo methodInfo12 = AccessTools.Method(typeof(SailInfoPatches), "CapstanPatch", (Type[])null, (Type[])null);
		if (winchesInfoConfig.Value)
		{
			val.Patch((MethodBase)methodInfo11, new HarmonyMethod(methodInfo12), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo5, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			if (coloredWinchesConfig.Value)
			{
				val.Patch((MethodBase)methodInfo7, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}
		if (rudderHUDConfig.Value)
		{
			val.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		val.Patch((MethodBase)methodInfo9, new HarmonyMethod(methodInfo10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}
}
public class WinchInfoSail : WinchInfo
{
	private Transform sailTransform;

	private Transform boatTransform;

	public Sail sailComponent;

	private FieldInfo unamplifiedForwardInfo;

	private FieldInfo unamplifiedSideInfo;

	private FieldInfo totalWindForceInfo;

	private string sailName;

	public SailNameType nameType;

	public override void Awake()
	{
		base.Awake();
		unamplifiedForwardInfo = AccessTools.Field(typeof(Sail), "unamplifiedForwardForce");
		unamplifiedSideInfo = AccessTools.Field(typeof(Sail), "unamplifiedSidewayForce");
		totalWindForceInfo = AccessTools.Field(typeof(Sail), "totalWindForce");
	}

	public string SailName()
	{
		if (SailInfoMain.sailNameConfig.Value == SailNameType.Standard)
		{
			return sailComponent.sailName;
		}
		if (sailName != null && sailName.Length > 0 && nameType == SailInfoMain.sailNameConfig.Value)
		{
			return sailName;
		}
		nameType = SailInfoMain.sailNameConfig.Value;
		sailName = SailInfoPatches.SailName(sailComponent, nameType);
		return sailName;
	}

	private int SailDegree()
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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)
		if ((Object)(object)sailTransform == (Object)null)
		{
			sailTransform = ((Component)sailComponent).transform;
		}
		if ((Object)(object)boatTransform == (Object)null)
		{
			boatTransform = ((Component)sailComponent.shipRigidbody).transform;
		}
		Vector3 forward = boatTransform.forward;
		Vector3 val = (sailComponent.squareSail ? sailTransform.up : sailTransform.right);
		int num = Mathf.RoundToInt(Vector3.SignedAngle(forward, val, Vector3.up));
		num = ((num > 90) ? (180 - num) : num);
		return (num < 0) ? (-num) : num;
	}

	private static int SailDegree(Sail sail)
	{
		//IL_000b: 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)
		//IL_0015: 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_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_003c: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = -((Component)GameState.currentBoat).transform.right;
		Vector3 val2 = (sail.squareSail ? ((Component)sail).transform.up : (-((Component)sail).transform.right));
		int num = Mathf.RoundToInt(Vector3.SignedAngle(val, val2, -Vector3.up));
		num = ((num > 90) ? (180 - num) : num);
		return (num < 0) ? (-num) : num;
	}

	private float SailEfficiency()
	{
		float num = (float)unamplifiedForwardInfo.GetValue(sailComponent);
		float totalForce = GetTotalForce();
		return Mathf.Round(num / totalForce * 100f);
	}

	private float SailInefficiency()
	{
		float num = (float)unamplifiedSideInfo.GetValue(sailComponent);
		float totalForce = GetTotalForce();
		return Mathf.Abs(Mathf.Round(num / totalForce * 100f));
	}

	private float CombinedEfficiency()
	{
		float num = SailEfficiency();
		if (num <= 0f)
		{
			return num;
		}
		float num2 = 100f - SailInefficiency();
		return Mathf.Round((num + num2) / 2f);
	}

	private float GetTotalForce()
	{
		float appliedWindForce = sailComponent.appliedWindForce;
		if (appliedWindForce == 0f)
		{
			return (float)totalWindForceInfo.GetValue(sailComponent);
		}
		return appliedWindForce / sailComponent.GetCapturedForceFraction();
	}

	public override string WinchHUD()
	{
		string text = "";
		float num = rope.currentLength;
		if (SailInfoMain.flipWinchesOutConfig.Value && SailInfoMain.winchesOutConfig.Value != 0)
		{
			RopeController obj = rope;
			RopeControllerSailReef val = (RopeControllerSailReef)(object)((obj is RopeControllerSailReef) ? obj : null);
			if (val != null && val.reverseReefing)
			{
				num = 1f - num;
			}
		}
		float num2 = Mathf.Round(num * 100f);
		if (rope is RopeControllerSailReef)
		{
			if (SailInfoMain.sailNameConfig.Value != 0)
			{
				text = text + "<size=70%>" + SailName() + " Halyard\n</size>";
			}
			if (SailInfoMain.winchesOutConfig.Value != 0)
			{
				text += $"<size=70%>{num2} out</size>";
			}
			if (SailInfoMain.winchesBarConfig.Value)
			{
				text += $"\n<size=3%>{Bar(num)}</size>";
			}
		}
		else
		{
			if (SailInfoMain.sailNameConfig.Value != 0)
			{
				text = text + "<size=70%>" + SailName() + "\n</size>";
			}
			if (SailInfoMain.sailEfficiencyConfig.Value)
			{
				text += $"<size=70%>Eff: {CombinedEfficiency()}% </size>";
			}
			if (SailInfoMain.sailForwardForceConfig.Value)
			{
				text += $"<size=70%>F: {SailEfficiency()}% </size>";
			}
			if (SailInfoMain.sailSidewaysForceConfig.Value)
			{
				text += $"<size=70%>S: {SailInefficiency()}% </size>";
			}
			if (SailInfoMain.winchesOutConfig.Value == WinchOutType.Degrees)
			{
				text += $"<size=70%>\n{SailDegree()}° out</size>";
			}
			else if (SailInfoMain.winchesOutConfig.Value == WinchOutType.Percent)
			{
				text += $"<size=70%>\n{num2} out</size>";
			}
			if (SailInfoMain.winchesBarConfig.Value)
			{
				text += $"\n<size=3%>{Bar(num)}</size>";
			}
		}
		return text;
	}
}