Decompiled source of ShipTweaks v1.0.0

plugins\ShipTweaks\ShipTweaks.dll

Decompiled a day 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 Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ShipTweaks")]
[assembly: AssemblyProduct("ShipTweaks")]
[assembly: AssemblyDescription("Configurable Valheim ship speed and rowing tweaks.")]
[assembly: AssemblyCompany("LEGIOmods")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially created with the assistance of OpenAI Codex for code generation, packaging, and documentation.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "OpenAI")]
[assembly: AssemblyMetadata("AI_Agent", "OpenAI Codex")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[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 ShipTweaks
{
	[BepInPlugin("domen.valheim.shiptweaks", "ShipTweaks", "1.0.0")]
	public sealed class ShipTweaksPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "domen.valheim.shiptweaks";

		public const string PluginName = "ShipTweaks";

		public const string PluginVersion = "1.0.0";

		private const string VanillaSpeedReference = "Vanilla reference values according to the Valheim Wiki: Raft paddle 1.6, half sail 1.7-2.2, full sail 2.2-3.1 m/s; Karve paddle 3.14, half sail 2.8-4.8, full sail 3.9-7.0 m/s; Longship paddle 3.16, half sail 3.6-6.7, full sail 5.0-9.75 m/s; Drakkar paddle 2.50, half sail 3.3-6.2, full sail 4.65-8.9 m/s.";

		private static Harmony _harmony;

		internal static ConfigEntry<float> EasyRowSpeedPercent;

		internal static ConfigEntry<float> EasyHalfSailSpeedPercent;

		internal static ConfigEntry<float> EasyFullSailSpeedPercent;

		internal static ConfigEntry<float> EasyMaxSpeedLimit;

		internal static ConfigEntry<float> EasyStormSpeedLimit;

		internal static ConfigEntry<bool> PassengerRowingEnabled;

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			BindConfig();
			_harmony = new Harmony("domen.valheim.shiptweaks");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ShipTweaks 1.0.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void OnGUI()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			if (!PassengerRowingEnabled.Value)
			{
				return;
			}
			Ship localShip = Ship.GetLocalShip();
			if (Object.op_Implicit((Object)(object)localShip))
			{
				Speed speedSetting = localShip.GetSpeedSetting();
				if ((int)speedSetting == 1 || (int)speedSetting == 2)
				{
					DrawRowingMultiplier(ShipTweaksState.CountPlayersOnShip(localShip));
				}
			}
		}

		private void BindConfig()
		{
			EasyRowSpeedPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Easy", "RowSpeedPercent", 150f, "Rowing and reverse speed in percent. 100 = vanilla, 150 = 50 percent stronger, 50 = half strength.");
			EasyHalfSailSpeedPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Easy", "HalfSailSpeedPercent", 125f, "Half sail speed in percent. 100 = vanilla.");
			EasyFullSailSpeedPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Easy", "FullSailSpeedPercent", 150f, "Full sail speed in percent. 100 = vanilla.");
			EasyMaxSpeedLimit = ((BaseUnityPlugin)this).Config.Bind<float>("Easy", "MaxSpeedLimit", 0f, "Hard speed limit in m/s. 0 = vanilla/no hard limit. Vanilla reference values according to the Valheim Wiki: Raft paddle 1.6, half sail 1.7-2.2, full sail 2.2-3.1 m/s; Karve paddle 3.14, half sail 2.8-4.8, full sail 3.9-7.0 m/s; Longship paddle 3.16, half sail 3.6-6.7, full sail 5.0-9.75 m/s; Drakkar paddle 2.50, half sail 3.3-6.2, full sail 4.65-8.9 m/s.");
			EasyStormSpeedLimit = ((BaseUnityPlugin)this).Config.Bind<float>("Easy", "StormSpeedLimit", 0f, "Hard speed limit during thunder or storm weather in m/s. 0 = vanilla/no extra storm limit. Vanilla reference values according to the Valheim Wiki: Raft paddle 1.6, half sail 1.7-2.2, full sail 2.2-3.1 m/s; Karve paddle 3.14, half sail 2.8-4.8, full sail 3.9-7.0 m/s; Longship paddle 3.16, half sail 3.6-6.7, full sail 5.0-9.75 m/s; Drakkar paddle 2.50, half sail 3.3-6.2, full sail 4.65-8.9 m/s.");
			PassengerRowingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Passenger rowing", "PassengerRowingEnabled", true, "When enabled, normal rowing force is multiplied by the number of players on the ship. Example: 3 players on the ship = 3x rowing force.");
		}

		internal static float RowMultiplier()
		{
			return PercentToMultiplier(EasyRowSpeedPercent.Value);
		}

		internal static float HalfSailMultiplier()
		{
			return PercentToMultiplier(EasyHalfSailSpeedPercent.Value);
		}

		internal static float FullSailMultiplier()
		{
			return PercentToMultiplier(EasyFullSailSpeedPercent.Value);
		}

		internal static float NormalSpeedLimit()
		{
			return Mathf.Max(0f, EasyMaxSpeedLimit.Value);
		}

		internal static float StormSpeedLimit()
		{
			return Mathf.Max(0f, EasyStormSpeedLimit.Value);
		}

		private static float PercentToMultiplier(float percent)
		{
			return Mathf.Max(0f, percent) / 100f;
		}

		private static void DrawRowingMultiplier(int playerCount)
		{
			//IL_0058: 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)
			//IL_0064: 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_0075: Expected O, but got Unknown
			//IL_007c: 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_00d6: 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)
			string text = "x" + Mathf.Max(1, playerCount);
			float num = (float)Screen.width - 158f;
			float num2 = (float)Screen.height * 0.5f + 36f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num, num2, 90f, 42f);
			GUIStyle val2 = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)3,
				fontSize = 30,
				fontStyle = (FontStyle)1
			};
			val2.normal.textColor = Color.black;
			GUI.Label(new Rect(((Rect)(ref val)).x + 2f, ((Rect)(ref val)).y + 2f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text, val2);
			val2.normal.textColor = new Color(1f, 0.74f, 0.12f, 1f);
			GUI.Label(val, text, val2);
		}
	}
	internal static class ShipTweaksState
	{
		internal static readonly FieldRef<Ship, Rigidbody> ShipBody = AccessTools.FieldRefAccess<Ship, Rigidbody>("m_body");

		internal static readonly FieldRef<Ship, List<Player>> ShipPlayers = AccessTools.FieldRefAccess<Ship, List<Player>>("m_players");

		internal static int CountPlayersOnShip(Ship ship)
		{
			if (!Object.op_Implicit((Object)(object)ship))
			{
				return 1;
			}
			List<Player> list = ShipPlayers.Invoke(ship);
			if (list == null || list.Count == 0)
			{
				return 1;
			}
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)list[i]))
				{
					num++;
				}
			}
			return Mathf.Max(1, num);
		}
	}
	[HarmonyPatch(typeof(Ship), "CustomFixedUpdate")]
	internal static class ShipCustomFixedUpdatePatch
	{
		internal readonly struct ShipForces
		{
			internal readonly float BackwardForce;

			internal readonly float SailForceFactor;

			internal ShipForces(float backwardForce, float sailForceFactor)
			{
				BackwardForce = backwardForce;
				SailForceFactor = sailForceFactor;
			}
		}

		private static void Prefix(Ship __instance, out ShipForces __state)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			__state = new ShipForces(__instance.m_backwardForce, __instance.m_sailForceFactor);
			Speed speedSetting = __instance.GetSpeedSetting();
			if ((int)speedSetting == 1 || (int)speedSetting == 2)
			{
				int num = ((!ShipTweaksPlugin.PassengerRowingEnabled.Value) ? 1 : ShipTweaksState.CountPlayersOnShip(__instance));
				__instance.m_backwardForce *= ShipTweaksPlugin.RowMultiplier() * (float)num;
			}
			else if ((int)speedSetting == 3)
			{
				__instance.m_sailForceFactor *= ShipTweaksPlugin.HalfSailMultiplier();
			}
			else if ((int)speedSetting == 4)
			{
				__instance.m_sailForceFactor *= ShipTweaksPlugin.FullSailMultiplier();
			}
		}

		private static void Postfix(Ship __instance, ShipForces __state)
		{
			__instance.m_backwardForce = __state.BackwardForce;
			__instance.m_sailForceFactor = __state.SailForceFactor;
			LimitSpeed(__instance);
		}

		private static void LimitSpeed(Ship ship)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003c: 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_0062: 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_006f: 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)
			float configuredSpeedLimit = GetConfiguredSpeedLimit();
			if (configuredSpeedLimit <= 0f)
			{
				return;
			}
			Rigidbody val = ShipTweaksState.ShipBody.Invoke(ship);
			if (Object.op_Implicit((Object)(object)val) && !val.isKinematic)
			{
				Vector3 linearVelocity = val.linearVelocity;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(linearVelocity.x, linearVelocity.z);
				if (!(((Vector2)(ref val2)).magnitude <= configuredSpeedLimit))
				{
					Vector2 val3 = ((Vector2)(ref val2)).normalized * configuredSpeedLimit;
					val.linearVelocity = new Vector3(val3.x, linearVelocity.y, val3.y);
				}
			}
		}

		private static float GetConfiguredSpeedLimit()
		{
			float num = ShipTweaksPlugin.StormSpeedLimit();
			if (num > 0f && IsStormWeather())
			{
				return num;
			}
			return ShipTweaksPlugin.NormalSpeedLimit();
		}

		private static bool IsStormWeather()
		{
			EnvMan instance = EnvMan.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return false;
			}
			EnvSetup currentEnvironment = instance.GetCurrentEnvironment();
			if (currentEnvironment == null || string.IsNullOrEmpty(currentEnvironment.m_name))
			{
				return false;
			}
			string text = currentEnvironment.m_name.ToLowerInvariant();
			if (!text.Contains("thunder"))
			{
				return text.Contains("storm");
			}
			return true;
		}
	}
}