Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Smooth Sailing v0.3.4
plugins/SmoothSailing.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using MagicaCloth2; using Microsoft.CodeAnalysis; using UnityEngine; [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("SmoothSailing")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+8ca184414935f658778b42b69a4425ec3c11c79d")] [assembly: AssemblyProduct("SmoothSailing")] [assembly: AssemblyTitle("SmoothSailing")] [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 SmoothSailing { [BepInPlugin("p377y.valheim.smoothsailing", "Smooth Sailing", "0.3.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal enum TailwindMode { Off, DeadAstern, PositiveOffset, NegativeOffset } internal enum WindIntensityMode { Vanilla, Minimum, Maximum } [CompilerGenerated] private static class <>O { public static CoroutineHandler <0>__OnTailwindModeServerReceive; public static CoroutineHandler <1>__OnTailwindModeClientReceive; } public const string ModGuid = "p377y.valheim.smoothsailing"; public const string ModName = "Smooth Sailing"; public const string ModVersion = "0.3.4"; internal static Plugin Instance; internal static ManualLogSource ModLog; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<TailwindMode> TailwindModeSetting; internal static ConfigEntry<float> OffsetAngle; internal static ConfigEntry<WindIntensityMode> WindIntensityModeSetting; internal static ConfigEntry<float> MinimumWindIntensity; internal static ConfigEntry<KeyboardShortcut> AdminToggleKey; internal static ConfigEntry<float> ShipExploreRadiusMultiplier; internal static ConfigEntry<float> ForwardRowMultiplier; internal static ConfigEntry<float> ReverseRowMultiplier; private static readonly Dictionary<Ship, MagicaWindZone> ShipWindZones = new Dictionary<Ship, MagicaWindZone>(); private Harmony _harmony; internal static CustomRPC TailwindModeRPC; private static readonly FieldInfo SailForceFactorField = AccessTools.Field(typeof(Ship), "m_sailForceFactor"); private static readonly FieldInfo SailForceField = AccessTools.Field(typeof(Ship), "m_sailForce"); private static readonly FieldInfo WindChangeVelocityField = AccessTools.Field(typeof(Ship), "m_windChangeVelocity"); private void Awake() { //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_003c: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //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_0057: Expected O, but got Unknown Instance = this; ModLog = ((BaseUnityPlugin)this).Logger; BindConfig(); NetworkManager instance = NetworkManager.Instance; object obj = <>O.<0>__OnTailwindModeServerReceive; if (obj == null) { CoroutineHandler val = OnTailwindModeServerReceive; <>O.<0>__OnTailwindModeServerReceive = val; obj = (object)val; } object obj2 = <>O.<1>__OnTailwindModeClientReceive; if (obj2 == null) { CoroutineHandler val2 = OnTailwindModeClientReceive; <>O.<1>__OnTailwindModeClientReceive = val2; obj2 = (object)val2; } TailwindModeRPC = instance.AddRPC("SmoothSailing_TailwindMode", (CoroutineHandler)obj, (CoroutineHandler)obj2); _harmony = new Harmony("p377y.valheim.smoothsailing"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Smooth Sailing 0.3.4 loaded."); } private static IEnumerator OnTailwindModeServerReceive(long sender, ZPackage package) { if (package == null || (Object)(object)ZNet.instance == (Object)null) { yield break; } int num = package.ReadInt(); if (!Enum.IsDefined(typeof(TailwindMode), num)) { ManualLogSource modLog = ModLog; if (modLog != null) { modLog.LogWarning((object)$"Rejected invalid Smooth Sailing tailwind mode {num} from peer {sender}."); } yield break; } ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null || peer.m_socket == null || !ZNet.instance.IsAdmin(peer.m_socket.GetHostName())) { ManualLogSource modLog2 = ModLog; if (modLog2 != null) { modLog2.LogWarning((object)$"Rejected Smooth Sailing tailwind mode change from non-admin peer {sender}."); } yield break; } TailwindMode tailwindMode = (TailwindMode)num; TailwindModeSetting.Value = tailwindMode; ZPackage val = new ZPackage(); val.Write((int)tailwindMode); TailwindModeRPC.SendPackage(ZNet.instance.GetPeers(), val); ManualLogSource modLog3 = ModLog; if (modLog3 != null) { modLog3.LogInfo((object)$"Tailwind mode changed to {tailwindMode} by admin peer {sender}."); } } private static IEnumerator OnTailwindModeClientReceive(long sender, ZPackage package) { if (package == null) { yield break; } int num = package.ReadInt(); if (!Enum.IsDefined(typeof(TailwindMode), num)) { ManualLogSource modLog = ModLog; if (modLog != null) { modLog.LogWarning((object)$"Received invalid Smooth Sailing tailwind mode {num} from server."); } yield break; } TailwindMode tailwindMode = (TailwindMode)num; TailwindModeSetting.Value = tailwindMode; if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)1, GetTailwindModeDisplay(tailwindMode), 0, (Sprite)null, false); } ManualLogSource modLog2 = ModLog; if (modLog2 != null) { modLog2.LogInfo((object)$"Tailwind mode synchronized to {tailwindMode}."); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } foreach (KeyValuePair<Ship, MagicaWindZone> shipWindZone in ShipWindZones) { if ((Object)(object)shipWindZone.Value != (Object)null) { Object.Destroy((Object)(object)((Component)shipWindZone.Value).gameObject); } } ShipWindZones.Clear(); } private void BindConfig() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, new ConfigDescription("Master switch for Smooth Sailing.", (AcceptableValueBase)null, new object[1] { val })); TailwindModeSetting = ((BaseUnityPlugin)this).Config.Bind<TailwindMode>("Tailwind", "Tailwind Mode", TailwindMode.DeadAstern, new ConfigDescription("Favorable-wind mode: Off, DeadAstern, PositiveOffset, or NegativeOffset.", (AcceptableValueBase)null, new object[1] { val })); OffsetAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Tailwind", "Offset Angle", 60f, new ConfigDescription("Wind angle used by PositiveOffset and NegativeOffset. 0 = dead astern; 60 is near peak vanilla sail efficiency.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 90f), new object[1] { val })); WindIntensityModeSetting = ((BaseUnityPlugin)this).Config.Bind<WindIntensityMode>("Tailwind", "Wind Intensity Mode", WindIntensityMode.Vanilla, new ConfigDescription("Sailing wind intensity while a favorable-wind mode is active: Vanilla uses world intensity, Minimum enforces the configured minimum, Maximum always uses full intensity.", (AcceptableValueBase)null, new object[1] { val })); MinimumWindIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Tailwind", "Minimum Wind Intensity", 0.5f, new ConfigDescription("Minimum sailing wind intensity used when Wind Intensity Mode is Minimum. Natural wind stronger than this value is preserved.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val })); AdminToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Tailwind", "Admin Toggle Key", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), "Local hotkey used by a server administrator to cycle Off -> DeadAstern -> PositiveOffset -> NegativeOffset."); ShipExploreRadiusMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Exploration", "Ship Exploration Radius Multiplier", 2f, new ConfigDescription("Multiplier applied to map exploration radius while aboard a ship. 1 = vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), new object[1] { val })); ForwardRowMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Rowing", "Forward Row Speed Multiplier", 1.5f, new ConfigDescription("Multiplier for forward rowing force (Slow speed). 1 = vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), new object[1] { val })); ReverseRowMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Rowing", "Backward Row Speed Multiplier", 2f, new ConfigDescription("Multiplier for reverse rowing force (Back speed). 1 = vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), new object[1] { val })); } internal static string GetTailwindModeDisplay(TailwindMode mode) { return mode switch { TailwindMode.DeadAstern => "Smooth Sailing: DEAD ASTERN", TailwindMode.PositiveOffset => $"Smooth Sailing: OFFSET +{OffsetAngle.Value:0.#}°", TailwindMode.NegativeOffset => $"Smooth Sailing: OFFSET -{OffsetAngle.Value:0.#}°", _ => "Smooth Sailing: OFF", }; } internal static bool IsTailwindEnabled() { if (Enabled.Value) { return TailwindModeSetting.Value != TailwindMode.Off; } return false; } internal static float GetTailwindAngle() { return TailwindModeSetting.Value switch { TailwindMode.PositiveOffset => OffsetAngle.Value, TailwindMode.NegativeOffset => 0f - OffsetAngle.Value, _ => 0f, }; } internal static Vector3 GetDesiredWindDirection(Ship ship) { //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) //IL_002a: 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_0009: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ship == (Object)null) { return Vector3.zero; } return Quaternion.AngleAxis(GetTailwindAngle(), ((Component)ship).transform.up) * ((Component)ship).transform.forward; } internal static float GetEffectiveWindIntensity(float worldIntensity) { if (!IsTailwindEnabled()) { return worldIntensity; } return WindIntensityModeSetting.Value switch { WindIntensityMode.Minimum => Mathf.Max(worldIntensity, MinimumWindIntensity.Value), WindIntensityMode.Maximum => 1f, _ => worldIntensity, }; } internal static MagicaWindZone GetOrCreateShipWindZone(Ship ship) { //IL_003d: 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_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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ship == (Object)null) { return null; } if (ShipWindZones.TryGetValue(ship, out var value) && (Object)(object)value != (Object)null) { return value; } MagicaCloth componentInChildren = ((Component)ship).GetComponentInChildren<MagicaCloth>(true); if ((Object)(object)componentInChildren == (Object)null) { return null; } GameObject val = new GameObject("SmoothSailing_SailWindZone"); val.transform.SetParent(((Component)componentInChildren).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; MagicaWindZone val2 = val.AddComponent<MagicaWindZone>(); val2.mode = (Mode)2; val2.size = new Vector3(12f, 12f, 4f); val2.main = 0f; val2.turbulence = 1f; val2.isAddition = false; ShipWindZones[ship] = val2; return val2; } internal static void UpdateShipWindZone(Ship ship) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ship == (Object)null) { return; } ShipWindZones.TryGetValue(ship, out var value); if (!IsSailingShip(ship)) { if ((Object)(object)value != (Object)null) { ((Behaviour)value).enabled = false; } return; } value = GetOrCreateShipWindZone(ship); if (!((Object)(object)value == (Object)null)) { if (!((Behaviour)value).enabled) { ((Behaviour)value).enabled = true; } value.SetWindDirection(GetDesiredWindDirection(ship), false); float effectiveWindIntensity = GetEffectiveWindIntensity(((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetWindIntensity() : 0f); value.main = Mathf.Pow(effectiveWindIntensity, 2f) * 100f; } } internal static void RemoveShipWindZone(Ship ship) { if (!((Object)(object)ship == (Object)null) && ShipWindZones.TryGetValue(ship, out var value)) { ShipWindZones.Remove(ship); if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } } internal static bool TryCalculateSmoothSailForce(Ship ship, float sailSize, float dt, out Vector3 result) { //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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_0159: 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_015d: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) result = Vector3.zero; if (!IsTailwindEnabled() || (Object)(object)ship == (Object)null || SailForceFactorField == null || SailForceField == null || WindChangeVelocityField == null) { return false; } if (!IsLocallyControlledSailingShip(ship) && !IsLocallyOwnedSailingShip(ship)) { return false; } Vector3 desiredWindDirection = GetDesiredWindDirection(ship); Vector3 normalized = ((Vector3)(ref desiredWindDirection)).normalized; float effectiveWindIntensity = GetEffectiveWindIntensity(((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetWindIntensity() : 0f); float num = Mathf.Lerp(0.25f, 1f, effectiveWindIntensity); float num2 = Vector3.Dot(normalized, -((Component)ship).transform.forward); float num3 = Mathf.Lerp(0.7f, 1f, 1f - Utils.Abs(num2)); float num4 = 1f - Utils.LerpStep(0.75f, 0.8f, num2); float num5 = num3 * num4 * num; float num6 = (float)SailForceFactorField.GetValue(ship); Vector3 val = (Vector3)SailForceField.GetValue(ship); Vector3 val2 = (Vector3)WindChangeVelocityField.GetValue(ship); Vector3 val3 = normalized + ((Component)ship).transform.forward; Vector3 val4 = ((((Vector3)(ref val3)).sqrMagnitude > 1E-06f) ? (((Vector3)(ref val3)).normalized * (num5 * num6 * sailSize)) : Vector3.zero); val = Vector3.SmoothDamp(val, val4, ref val2, 1f, 99f, dt); SailForceField.SetValue(ship, val); WindChangeVelocityField.SetValue(ship, val2); result = val; return true; } internal static bool IsLocallyControlledSailingShip(Ship ship) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_003c: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 if (!IsTailwindEnabled() || (Object)(object)ship == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } if ((Object)(object)Player.m_localPlayer.GetControlledShip() != (Object)(object)ship) { return false; } Speed speedSetting = ship.GetSpeedSetting(); if ((int)speedSetting != 3) { return (int)speedSetting == 4; } return true; } internal static bool IsSailingShip(Ship ship) { //IL_0013: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 if (!IsTailwindEnabled() || (Object)(object)ship == (Object)null) { return false; } Speed speedSetting = ship.GetSpeedSetting(); if ((int)speedSetting != 3) { return (int)speedSetting == 4; } return true; } internal static bool IsLocallyOwnedSailingShip(Ship ship) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0035: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 if (!IsTailwindEnabled() || (Object)(object)ship == (Object)null) { return false; } ZNetView component = ((Component)ship).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsOwner()) { return false; } Speed speedSetting = ship.GetSpeedSetting(); if ((int)speedSetting != 3) { return (int)speedSetting == 4; } return true; } internal static bool IsLocalPlayerAboardAnyShip() { if (Enabled.Value && (Object)(object)Player.m_localPlayer != (Object)null) { return ((Character)Player.m_localPlayer).IsAttachedToShip(); } return false; } } [HarmonyPatch(typeof(Player), "Update")] internal static class PlayerUpdateHotkeyPatch { private static bool _toggleWasDown; private static void Postfix(Player __instance) { //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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } KeyboardShortcut value = Plugin.AdminToggleKey.Value; if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { _toggleWasDown = false; } else { if (_toggleWasDown) { return; } _toggleWasDown = true; if ((Object)(object)ZNet.instance == (Object)null || !SynchronizationManager.Instance.PlayerIsAdmin) { ((Character)__instance).Message((MessageType)1, "Smooth Sailing: Admin only", 0, (Sprite)null, false); return; } Plugin.TailwindMode tailwindMode = Plugin.TailwindModeSetting.Value switch { Plugin.TailwindMode.Off => Plugin.TailwindMode.DeadAstern, Plugin.TailwindMode.DeadAstern => Plugin.TailwindMode.PositiveOffset, Plugin.TailwindMode.PositiveOffset => Plugin.TailwindMode.NegativeOffset, _ => Plugin.TailwindMode.Off, }; if (ZNet.instance.IsServer()) { Plugin.TailwindModeSetting.Value = tailwindMode; ((Character)__instance).Message((MessageType)1, Plugin.GetTailwindModeDisplay(tailwindMode), 0, (Sprite)null, false); ManualLogSource modLog = Plugin.ModLog; if (modLog != null) { modLog.LogInfo((object)$"Tailwind mode changed locally to {tailwindMode}."); } return; } ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer == null) { ManualLogSource modLog2 = Plugin.ModLog; if (modLog2 != null) { modLog2.LogWarning((object)"Could not send tailwind mode change: server peer not found."); } } else { ZPackage val = new ZPackage(); val.Write((int)tailwindMode); Plugin.TailwindModeRPC.SendPackage(serverPeer.m_uid, val); } } } } internal static class MinimapRealWindScope { internal static bool UpdatingWindMarker; } [HarmonyPatch(typeof(Minimap), "UpdateWindMarker")] internal static class MinimapUpdateWindMarkerScopePatch { private static void Prefix() { MinimapRealWindScope.UpdatingWindMarker = true; } private static void Postfix() { MinimapRealWindScope.UpdatingWindMarker = false; } private static Exception Finalizer(Exception __exception) { MinimapRealWindScope.UpdatingWindMarker = false; return __exception; } } internal static class ShipHudWindScope { internal static bool UpdatingShipHud; } [HarmonyPatch(typeof(Hud), "UpdateShipHud")] internal static class HudUpdateShipHudPatch { private static void Prefix() { ShipHudWindScope.UpdatingShipHud = true; } private static void Postfix() { ShipHudWindScope.UpdatingShipHud = false; } private static Exception Finalizer(Exception __exception) { ShipHudWindScope.UpdatingShipHud = false; return __exception; } } [HarmonyPatch(typeof(Ship), "GetWindAngleFactor")] internal static class ShipGetWindAngleFactorPatch { private static void Postfix(Ship __instance, ref float __result) { //IL_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references) if (Plugin.IsTailwindEnabled() && !((Object)(object)__instance == (Object)null) && (Plugin.IsLocallyControlledSailingShip(__instance) || Plugin.IsLocallyOwnedSailingShip(__instance))) { float num = Vector3.Dot(Plugin.GetDesiredWindDirection(__instance), -((Component)__instance).transform.forward); float num2 = Mathf.Lerp(0.7f, 1f, 1f - Utils.Abs(num)); float num3 = 1f - Utils.LerpStep(0.75f, 0.8f, num); __result = num2 * num3; } } } [HarmonyPatch(typeof(Ship), "GetWindAngle")] internal static class ShipGetWindAnglePatch { private static void Postfix(Ship __instance, ref float __result) { if (ShipHudWindScope.UpdatingShipHud && Plugin.IsTailwindEnabled() && (Plugin.IsLocallyControlledSailingShip(__instance) || Plugin.IsLocallyOwnedSailingShip(__instance))) { float tailwindAngle = Plugin.GetTailwindAngle(); __result = Mathf.Repeat(360f - tailwindAngle, 360f); } } } internal static class ShipSailForceScope { internal static bool CalculatingSailForce; internal static Ship CurrentShip; } [HarmonyPatch(typeof(Ship), "GetSailForce")] internal static class ShipGetSailForceScopePatch { private static bool Prefix(Ship __instance, float sailSize, float dt, ref Vector3 __result) { //IL_0019: 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) ShipSailForceScope.CalculatingSailForce = true; ShipSailForceScope.CurrentShip = __instance; if (Plugin.TryCalculateSmoothSailForce(__instance, sailSize, dt, out var result)) { __result = result; ShipSailForceScope.CalculatingSailForce = false; ShipSailForceScope.CurrentShip = null; return false; } return true; } private static void Postfix() { ShipSailForceScope.CalculatingSailForce = false; ShipSailForceScope.CurrentShip = null; } private static Exception Finalizer(Exception __exception) { ShipSailForceScope.CalculatingSailForce = false; ShipSailForceScope.CurrentShip = null; return __exception; } } [HarmonyPatch(typeof(Ship), "CustomFixedUpdate", new Type[] { typeof(float) })] internal static class ShipCustomFixedUpdatePatch { internal sealed class State { public float BackwardForce; public bool Modified; } private static readonly FieldInfo BackwardForceField = AccessTools.Field(typeof(Ship), "m_backwardForce"); private static void Prefix(Ship __instance, out State __state) { //IL_0037: 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_003f: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 __state = new State(); if (!Plugin.Enabled.Value || (Object)(object)__instance == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsOwner()) { Speed speedSetting = __instance.GetSpeedSetting(); if (((int)speedSetting == 2 || (int)speedSetting == 1) && !(BackwardForceField == null)) { __state.BackwardForce = (float)BackwardForceField.GetValue(__instance); __state.Modified = true; float num = (((int)speedSetting == 2) ? Plugin.ForwardRowMultiplier.Value : Plugin.ReverseRowMultiplier.Value); BackwardForceField.SetValue(__instance, __state.BackwardForce * num); } } } private static void Postfix(Ship __instance, State __state) { if (__state != null && __state.Modified && !((Object)(object)__instance == (Object)null)) { BackwardForceField?.SetValue(__instance, __state.BackwardForce); } } } [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] internal static class MinimapExplorePatch { private static void Prefix(ref float radius) { if (Plugin.Enabled.Value && Plugin.IsLocalPlayerAboardAnyShip()) { radius *= Plugin.ShipExploreRadiusMultiplier.Value; } } } [HarmonyPatch(typeof(Ship), "UpdateSail")] internal static class ShipUpdateSailPatch { private static void Postfix(Ship __instance, float dt) { //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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_009f: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Plugin.UpdateShipWindZone(__instance); if (Plugin.IsTailwindEnabled() && Plugin.IsSailingShip(__instance) && !((Object)(object)__instance.m_mastObject == (Object)null)) { Vector3 desiredWindDirection = Plugin.GetDesiredWindDirection(__instance); desiredWindDirection = Vector3.Cross(Vector3.Cross(desiredWindDirection, ((Component)__instance).transform.up), ((Component)__instance).transform.up); float num = 0.5f + Vector3.Dot(((Component)__instance).transform.forward, desiredWindDirection) * 0.5f; Quaternion val = Quaternion.LookRotation(-Vector3.Lerp(desiredWindDirection, Vector3.Normalize(desiredWindDirection - ((Component)__instance).transform.forward), num), ((Component)__instance).transform.up); __instance.m_mastObject.transform.rotation = Quaternion.RotateTowards(__instance.m_mastObject.transform.rotation, val, 30f * dt); } } } [HarmonyPatch(typeof(Ship), "OnDisable")] internal static class ShipOnDisablePatch { private static void Prefix(Ship __instance) { Plugin.RemoveShipWindZone(__instance); } } [HarmonyPatch(typeof(EnvMan), "GetWindDir")] internal static class EnvManGetWindDirPatch { private static void Postfix(ref Vector3 __result) { //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_0060: 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) if (ShipSailForceScope.CalculatingSailForce && Plugin.IsTailwindEnabled() && (Object)(object)ShipSailForceScope.CurrentShip != (Object)null) { __result = Plugin.GetDesiredWindDirection(ShipSailForceScope.CurrentShip); } else if (!MinimapRealWindScope.UpdatingWindMarker && Plugin.IsTailwindEnabled()) { Player localPlayer = Player.m_localPlayer; Ship ship = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetControlledShip() : null); if (Plugin.IsLocallyControlledSailingShip(ship)) { __result = Plugin.GetDesiredWindDirection(ship); } } } } }