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 EasyRowSpeedPercent; internal static ConfigEntry EasyHalfSailSpeedPercent; internal static ConfigEntry EasyFullSailSpeedPercent; internal static ConfigEntry EasyMaxSpeedLimit; internal static ConfigEntry EasyStormSpeedLimit; internal static ConfigEntry 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("Easy", "RowSpeedPercent", 150f, "Rowing and reverse speed in percent. 100 = vanilla, 150 = 50 percent stronger, 50 = half strength."); EasyHalfSailSpeedPercent = ((BaseUnityPlugin)this).Config.Bind("Easy", "HalfSailSpeedPercent", 125f, "Half sail speed in percent. 100 = vanilla."); EasyFullSailSpeedPercent = ((BaseUnityPlugin)this).Config.Bind("Easy", "FullSailSpeedPercent", 150f, "Full sail speed in percent. 100 = vanilla."); EasyMaxSpeedLimit = ((BaseUnityPlugin)this).Config.Bind("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("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("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 ShipBody = AccessTools.FieldRefAccess("m_body"); internal static readonly FieldRef> ShipPlayers = AccessTools.FieldRefAccess>("m_players"); internal static int CountPlayersOnShip(Ship ship) { if (!Object.op_Implicit((Object)(object)ship)) { return 1; } List 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; } } }