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 ShipNavigator v1.2.0
plugins/ShipNavigator.dll
Decompiled 2 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using ShipNavigator.Patches; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Ship Navigator")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Ship Navigator")] [assembly: AssemblyCopyright("JustCrazy © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("743b8e17-c591-4efe-8195-8109a986eccc")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [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 ShipNavigator { public class PIDController { private double error; private double integral; private double derivative; private double Kp; private double Ki; private double Kd; private double lastError; private float setpoint; private float outputMin; private float outputMax; private bool isInvertedOutput; public double P; public double I; public double D; public double Sum; public double d_Output; public float SetPoint { get { return setpoint; } set { setpoint = value; } } public float OutputMin { get { return outputMin; } set { outputMin = value; } } public float OutputMax { get { return outputMax; } set { outputMax = value; } } public bool IsInvertedOutput { get { return isInvertedOutput; } set { isInvertedOutput = value; } } public PIDController(double Kp, double Ki, double Kd, float setPoint, float outMin, float outMax, bool invertedOutput = false) { this.Kp = Kp; this.Ki = Ki; this.Kd = Kd; setpoint = setPoint; outputMin = outMin; outputMax = outMax; isInvertedOutput = invertedOutput; } public float Update(double input, double dt) { error = (double)setpoint - input; integral += error * dt; integral = Math.Min(Math.Max(integral, outputMin), outputMax); derivative = (error - lastError) / dt; lastError = error; P = Kp * error; I = Ki * integral; D = Kd * derivative; Sum = P + I + D; double val = Kp * error + Ki * integral + Kd * derivative; val = Math.Min(Math.Max(val, outputMin), outputMax); if (!isInvertedOutput) { return (float)val; } return 0f - (float)val; } public void SetFactors(double Kp, double Ki, double Kd) { this.Kp = Kp; this.Ki = Ki; this.Kd = Kd; } } [BepInPlugin("JustCrazy.Valheim.ShipNavigator", "Ship Navigator", "1.2.0")] [BepInProcess("valheim.exe")] [BepInProcess("valheim.x86_64")] public class ShipNavigator : BaseUnityPlugin { public const string ModGuid = "JustCrazy.Valheim.ShipNavigator"; public const string ModName = "Ship Navigator"; public const string ModVersion = "1.2.0"; private static Harmony harmonyInstance; private ConfigEntry<SteeringMode> steeringMode; private ConfigEntry<bool> applyMastParking; private ConfigEntry<KeyboardShortcut> SteeringModeSwitchKey; private ConfigEntry<KeyboardShortcut> SteerToPointerKey; private ConfigEntry<KeyboardShortcut> SteerViaMinimapKey; private ConfigEntry<KeyboardShortcut> ShipCameraModeKey; private ConfigEntry<int> ShipHudPosHorizontal; private ConfigEntry<int> ShipHudPosVertical; public void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown LoadSettings(); harmonyInstance = new Harmony("JustCrazy.Valheim.ShipNavigator"); harmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); } public void Update() { //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_0076: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.GetControlledShip() != (Object)null) { KeyboardShortcut value = SteeringModeSwitchKey.Value; if (((KeyboardShortcut)(ref value)).IsUp()) { Ship_Patch.isAutoSteerOn = !Ship_Patch.isAutoSteerOn; ((Character)Player.m_localPlayer).Message((MessageType)2, "Steering mode: " + (Ship_Patch.isAutoSteerOn ? "Automatic" : "Manual"), 0, (Sprite)null, false); } KeyboardShortcut value2 = SteerToPointerKey.Value; if (((KeyboardShortcut)(ref value2)).IsPressed()) { Ship_Patch.steerDirection = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : Vector3.zero); } KeyboardShortcut value3 = SteerViaMinimapKey.Value; Minimap_Patch.isAllowedSetDirection = ((KeyboardShortcut)(ref value3)).IsPressed(); KeyboardShortcut value4 = ShipCameraModeKey.Value; GameCamera_Patch.isCameraModeChanged = ((KeyboardShortcut)(ref value4)).IsUp(); } } public void OnDestroy() { Harmony obj = harmonyInstance; if (obj != null) { obj.UnpatchSelf(); } } private void LoadSettings() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_009e: 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_00b8: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_0149: 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_0163: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: 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 ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 885, new ConfigDescription("Nexus mod ID for updates", (AcceptableValueBase)null, Array.Empty<object>())); steeringMode = ((BaseUnityPlugin)this).Config.Bind<SteeringMode>("General", "Steering Mode", SteeringMode.Automatic, new ConfigDescription("Default steering mode when starting the game.\nAutomatic: Use the auto steering mode\nManual: Old fashioned way to control your boat", (AcceptableValueBase)null, Array.Empty<object>())); applyMastParking = ((BaseUnityPlugin)this).Config.Bind<bool>("Optional Features", "Mast Parking", false, new ConfigDescription("If enabled, when the sails are lowered, it turning the mast along the ship's deck line, might make it easier to maneuver in really small spaces.", (AcceptableValueBase)null, Array.Empty<object>())); SteerToPointerKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Key Bindings", "Auto Steer to Pointer", new KeyboardShortcut((KeyCode)324, Array.Empty<KeyCode>()), new ConfigDescription("If steering mode set to [Automatic], while click / holding this button, your ship will turn automatically in the way you look and try to keep this direction after.", (AcceptableValueBase)null, Array.Empty<object>())); SteeringModeSwitchKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Key Bindings", "Switch Steering Mode", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), new ConfigDescription("Allow to switch steering mode on the fly (Doesn't affect default steering mode setting)", (AcceptableValueBase)null, Array.Empty<object>())); ShipCameraModeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Key Bindings", "Ship Camera Mode", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), new ConfigDescription("Change camera mode while steering.", (AcceptableValueBase)null, Array.Empty<object>())); SteerViaMinimapKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Key Bindings", "Auto Steer via Minimap", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), new ConfigDescription("If steering mode set to [Automatic], hold this button and click on the world map to turn your ship towards this point.", (AcceptableValueBase)null, Array.Empty<object>())); ShipHudPosHorizontal = ((BaseUnityPlugin)this).Config.Bind<int>("Ship HUD Position", "Horizontal", 50, new ConfigDescription("Horizontal position on screen (%)\n0 to 100 (Left - Right)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ShipHudPosVertical = ((BaseUnityPlugin)this).Config.Bind<int>("Ship HUD Position", "Vertical", 20, new ConfigDescription("Vertical position on screen (%)\n0 to 100 (Bottom - Top)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ShipHudPosHorizontal.SettingChanged += delegate { UpdateSettings(); }; ShipHudPosVertical.SettingChanged += delegate { UpdateSettings(); }; applyMastParking.SettingChanged += delegate { UpdateSettings(); }; steeringMode.SettingChanged += delegate { UpdateSettings(); }; UpdateSettings(); } private void UpdateSettings() { Hud_Patch.shipHudPosX = (float)ShipHudPosHorizontal.Value / 100f; Hud_Patch.shipHudPosY = (float)ShipHudPosVertical.Value / 100f; Ship_Patch.isAutoSteerOn = steeringMode.Value == SteeringMode.Automatic; Ship_Patch.isParkingMast = applyMastParking.Value; } } internal enum SteeringMode { Manual, Automatic } } namespace ShipNavigator.Patches { internal class GameCamera_Patch { public static ShipCameraMode nextCameraMode; public static bool isCameraModeChanged; [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] [HarmonyPostfix] public static void GameCamera_UpdateCamera_Postfix(GameCamera __instance, float ___m_distance) { //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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Ship val = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetControlledShip() : null); if ((Object)(object)val == (Object)null || (Object)(object)val.m_floatCollider == (Object)null) { return; } Vector3 size = val.m_floatCollider.size; switch (nextCameraMode) { case ShipCameraMode.Front: ((Component)__instance).transform.position = ((Component)val).transform.position + ((Component)val).transform.forward * (size.x - 0.3f) + ((Component)val).transform.up * 3f; __instance.m_fov = 80f; if (isCameraModeChanged) { nextCameraMode = ShipCameraMode.Rear; ((Character)localPlayer).Message((MessageType)1, "Camera: Rear (Rufa)", 0, (Sprite)null, false); } break; case ShipCameraMode.Rear: ((Component)__instance).transform.position = ((Component)val).transform.position - ((Component)val).transform.forward * (size.x - 0.3f) + ((Component)val).transform.up * 3f; ((Component)__instance).transform.rotation = ((Component)__instance).transform.rotation * Quaternion.Euler(0f, 180f, 0f); __instance.m_fov = 80f; if (isCameraModeChanged) { nextCameraMode = ShipCameraMode.Top; ((Character)localPlayer).Message((MessageType)1, "Camera: Top (Z góry)", 0, (Sprite)null, false); } break; case ShipCameraMode.Top: ((Component)__instance).transform.position = ((Component)val).transform.position + Vector3.up * (size.z + ___m_distance + 1.3f); __instance.m_fov = 80f; if (isCameraModeChanged) { nextCameraMode = ShipCameraMode.Default; ((Character)localPlayer).Message((MessageType)1, "Camera: Default (Domyślna)", 0, (Sprite)null, false); } break; default: if (isCameraModeChanged) { nextCameraMode = ShipCameraMode.Front; ((Character)localPlayer).Message((MessageType)1, "Camera: Front (Dziób)", 0, (Sprite)null, false); } break; } } } internal class Hud_Patch { internal static float shipHudPosX; internal static float shipHudPosY; [HarmonyPatch(typeof(Hud), "UpdateShipHud")] [HarmonyPostfix] public static void Hud_UpdateShipHud_Postfix(Hud __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_shipControlsRoot != (Object)null) { __instance.m_shipControlsRoot.transform.position = new Vector3((float)Screen.width * shipHudPosX, (float)Screen.height * shipHudPosY, 0f); } } } [HarmonyPatch(typeof(Minimap), "Start")] internal class Minimap_Patch { private delegate Vector3 ScreenToWorldPointDelegate(Vector3 screenPos); private static ScreenToWorldPointDelegate ScreenToWorldPoint; internal static bool isAllowedSetDirection; [HarmonyPostfix] public static void Postfix(Minimap __instance) { try { MethodInfo methodInfo = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null); if (methodInfo != null) { ScreenToWorldPoint = (ScreenToWorldPointDelegate)Delegate.CreateDelegate(typeof(ScreenToWorldPointDelegate), __instance, methodInfo); } } catch (Exception ex) { Debug.LogWarning((object)("[ShipNavigator] Failed to bind ScreenToWorldPoint: " + ex)); } if (!((Object)(object)__instance != (Object)null) || !((Object)(object)__instance.m_mapImageLarge != (Object)null)) { return; } UIInputHandler component = ((Component)__instance.m_mapImageLarge).GetComponent<UIInputHandler>(); if ((Object)(object)component != (Object)null) { component.m_onLeftUp = (Action<UIInputHandler>)Delegate.Combine(component.m_onLeftUp, (Action<UIInputHandler>)delegate { SetDirection(); }); } } private static void SetDirection() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0059: 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_0061: Unknown result type (might be due to invalid IL or missing references) if (isAllowedSetDirection) { Player localPlayer = Player.m_localPlayer; Ship val = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetControlledShip() : null); if (!((Object)(object)val == (Object)null)) { Vector3 position = ((Component)val).transform.position; Vector3 val2 = ((ScreenToWorldPoint != null) ? ScreenToWorldPoint(Input.mousePosition) : Vector3.zero) - position; Ship_Patch.steerDirection = ((Vector3)(ref val2)).normalized; } } } } public enum ShipCameraMode { Default, Front, Rear, Top } public static class Ship_Patch { [HarmonyPatch] public static class ApplyControls_Patch { [HarmonyTargetMethod] public static MethodBase TargetMethod() { return AccessTools.Method(typeof(Ship), "ApplyControls", new Type[1] { typeof(Vector3) }, (Type[])null) ?? AccessTools.Method(typeof(Ship), "ApplyControlls", new Type[1] { typeof(Vector3) }, (Type[])null); } [HarmonyPrefix] public static void Prefix(Ship __instance, ref Vector3 dir, Rigidbody ___m_body) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_003c: 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) if (isAutoSteerOn && (Object)(object)___m_body != (Object)null) { Speed speedSetting = __instance.GetSpeedSetting(); float speed = __instance.GetSpeed(); float x = ((((int)speedSetting == 1 && speed > 0f) || ((int)speedSetting != 1 && speed < 0f)) ? RudderToNeutralPosition(__instance) : rudderPID.Update(GetCourseError(__instance, steerDirection, ___m_body.angularVelocity.y), Time.fixedDeltaTime)); dir.x = x; } } } [HarmonyPatch(typeof(Ship), "Awake")] public static class Awake_Patch { [HarmonyPostfix] public static void Postfix(Ship __instance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //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) if (isParkingMast && (Object)(object)__instance.m_mastObject != (Object)null) { __instance.m_mastObject.transform.rotation = Quaternion.LookRotation(((Component)__instance).transform.right, ((Component)__instance).transform.up); } } } [HarmonyPatch(typeof(Ship), "UpdateSail")] public static class UpdateSail_Patch { [HarmonyPrefix] public static void Prefix(Ship __instance, float dt) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (isParkingMast && (Object)(object)__instance.m_mastObject != (Object)null) { UpdateSailSize?.Invoke(__instance, new object[1] { dt }); if (!__instance.IsSailUp()) { Quaternion val = Quaternion.LookRotation(((Component)__instance).transform.right, ((Component)__instance).transform.up); __instance.m_mastObject.transform.rotation = Quaternion.RotateTowards(__instance.m_mastObject.transform.rotation, val, 30f * dt); } } } } private static readonly MethodInfo UpdateSailSize = AccessTools.Method(typeof(Ship), "UpdateSailSize", new Type[1] { typeof(float) }, (Type[])null); internal static PIDController rudderPID = new PIDController(3.0, 0.003, 6.0, 0f, -1f, 1f); internal static Vector3 steerDirection; internal static bool isAutoSteerOn; internal static bool isParkingMast; public static float RudderToNeutralPosition(Ship ship) { return 0f - Mathf.Clamp(((Object)(object)ship != (Object)null) ? ship.GetRudderValue() : 0f, -1f, 1f); } public static float GetCourseError(Ship ship, Vector3 direction, float angVel) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0025: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = ((Component)ship).transform.forward; direction.y = 0f; forward.y = 0f; float num = Vector3.SignedAngle(forward, direction, Vector3.up); if ((int)ship.GetSpeedSetting() == 1) { angVel = 0f - angVel; num = 0f - Vector3.SignedAngle(-forward, direction, Vector3.up); if (Math.Abs(num) > 90f) { num += ((num < 0f) ? 180f : (-180f)); } } return angVel - num / 40f; } } }