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 SteadyHelm v1.0.0
SteadyHelm.dll
Decompiled a month agousing System; 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 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("SteadyHelm")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+fff128389933172fc3a2aa07de470d09976fb9b6")] [assembly: AssemblyProduct("SteadyHelm")] [assembly: AssemblyTitle("SteadyHelm")] [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 SteadyHelm { [HarmonyPatch] internal static class Autopilot { private sealed class Pid { private readonly double _kp; private readonly double _ki; private readonly double _kd; private readonly float _min; private readonly float _max; private double _integral; private double _lastError; private bool _primed; internal Pid(double kp, double ki, double kd, float min, float max) { _kp = kp; _ki = ki; _kd = kd; _min = min; _max = max; } internal void Reset() { _integral = 0.0; _lastError = 0.0; _primed = false; } internal float Update(double error, double dt) { if (dt <= 0.0) { return 0f; } _integral = Clamp(_integral + error * dt); double num = (_primed ? ((error - _lastError) / dt) : 0.0); _lastError = error; _primed = true; return (float)(0.0 - Clamp(_kp * error + _ki * _integral + _kd * num)); } private double Clamp(double value) { if (!(value < (double)_min)) { if (!(value > (double)_max)) { return value; } return _max; } return _min; } } internal static bool Active; private static readonly Pid Rudder = new Pid(3.0, 0.003, 6.0, -1f, 1f); private static Vector3 _course; private static Ship _helm; private static bool _steeringByHand; internal static void TrackHelm(Ship ship) { if (!((Object)(object)ship == (Object)(object)_helm)) { _helm = ship; _steeringByHand = false; if ((Object)(object)ship != (Object)null) { HoldCurrentCourse(ship); } } } internal static void HoldCurrentCourse(Ship ship) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) SetCourse(((Component)ship).transform.forward); } internal static void SetCourse(Vector3 direction) { //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) direction.y = 0f; if (!(((Vector3)(ref direction)).sqrMagnitude < 0.0001f)) { _course = ((Vector3)(ref direction)).normalized; Rudder.Reset(); } } [HarmonyPatch(typeof(Ship), "ApplyControlls")] [HarmonyPrefix] private static void Steer(Ship __instance, ref Vector3 dir, Rigidbody ___m_body) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!Active || (Object)(object)__instance != (Object)(object)_helm || (Object)(object)___m_body == (Object)null) { return; } if (Mathf.Abs(dir.x) > 0.01f) { _steeringByHand = true; return; } if (_steeringByHand) { _steeringByHand = false; HoldCurrentCourse(__instance); } Speed speedSetting = __instance.GetSpeedSetting(); float speed = __instance.GetSpeed(); bool flag = ((int)speedSetting == 1 && speed > 0f) || ((int)speedSetting != 1 && speed < 0f); dir.x = (flag ? (0f - Mathf.Clamp(__instance.GetRudderValue(), -1f, 1f)) : Rudder.Update(CourseError(__instance, _course, ___m_body.angularVelocity.y), Time.fixedDeltaTime)); } private static float CourseError(Ship ship, Vector3 course, float yawRate) { //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_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_001a: 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_002c: Invalid comparison between Unknown and I4 //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_0038: 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) Vector3 forward = ((Component)ship).transform.forward; forward.y = 0f; float num = Vector3.SignedAngle(forward, course, Vector3.up); if ((int)ship.GetSpeedSetting() == 1) { yawRate = 0f - yawRate; num = 0f - Vector3.SignedAngle(-forward, course, Vector3.up); if (Mathf.Abs(num) > 90f) { num += ((num < 0f) ? 180f : (-180f)); } } return yawRate - num / 40f; } } internal static class GameAccess { private static readonly Func<Minimap, Vector3, Vector3> ScreenToWorld = AccessTools.MethodDelegate<Func<Minimap, Vector3, Vector3>>(AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null), (object)null, true); internal static bool SelfTest(out string problem) { try { RuntimeHelpers.RunClassConstructor(typeof(GameAccess).TypeHandle); problem = null; return ScreenToWorld != null; } catch (Exception ex) { problem = ex.Message; return false; } } internal static bool TryScreenToWorldPoint(Minimap map, Vector3 screen, out Vector3 world) { //IL_0001: 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_001d: Unknown result type (might be due to invalid IL or missing references) world = default(Vector3); if (ScreenToWorld == null) { return false; } world = ScreenToWorld(map, screen); return true; } } [HarmonyPatch] internal static class MapCourse { internal static bool Armed; [HarmonyPatch(typeof(Minimap), "Start")] [HarmonyPostfix] private static void Hook(Minimap __instance) { if ((Object)(object)__instance.m_mapImageLarge == (Object)null) { return; } UIInputHandler component = ((Component)__instance.m_mapImageLarge).GetComponent<UIInputHandler>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogWarning((object)"Large map has no input handler; setting a course on the map is off this run."); return; } Minimap map = __instance; component.m_onLeftUp = (Action<UIInputHandler>)Delegate.Combine(component.m_onLeftUp, (Action<UIInputHandler>)delegate { OnMapClick(map); }); } private static void OnMapClick(Minimap map) { //IL_003a: 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_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) if (!Armed || (Object)(object)map == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; Ship val = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetControlledShip() : null); if (!((Object)(object)val == (Object)null) && GameAccess.TryScreenToWorldPoint(map, UnityInput.Current.mousePosition, out var world)) { Autopilot.SetCourse(world - ((Component)val).transform.position); if (!Autopilot.Active) { Autopilot.Active = true; } Plugin.Say("Course set"); } } } internal enum SteeringMode { Manual, Automatic } [BepInPlugin("matheba.steadyhelm", "SteadyHelm", "1.0.0")] [BepInProcess("valheim.exe")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<SteeringMode> StartMode; internal static ConfigEntry<bool> ShowMessages; internal static ConfigEntry<KeyboardShortcut> AimKey; internal static ConfigEntry<KeyboardShortcut> SwitchModeKey; internal static ConfigEntry<KeyboardShortcut> MapCourseKey; internal static ConfigEntry<KeyboardShortcut> CameraKey; internal static ConfigEntry<bool> MoveShipHud; internal static ConfigEntry<int> ShipHudHorizontal; internal static ConfigEntry<int> ShipHudVertical; private readonly Harmony _harmony = new Harmony("matheba.steadyhelm"); private void Awake() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; StartMode = ((BaseUnityPlugin)this).Config.Bind<SteeringMode>("1 - General", "Steering mode on start", SteeringMode.Automatic, "Automatic: the helm holds the course you aim at. Manual: the normal game."); ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Show messages", true, "Centre-screen messages when you switch mode, set a course on the map or change camera."); AimKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Keys", "Aim course", new KeyboardShortcut((KeyCode)324, Array.Empty<KeyCode>()), "In automatic mode, hold this and look where you want to go. The ship turns there and keeps that course after you let go."); SwitchModeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Keys", "Switch steering mode", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Switches between automatic and manual while you are at the helm."); MapCourseKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Keys", "Set course on map", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "Hold this and click a spot on the large map to point the ship at it. Turns automatic mode on."); CameraKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Keys", "Cycle ship camera", new KeyboardShortcut((KeyCode)118, Array.Empty<KeyCode>()), "Cycles the camera between normal, the bow and high overhead while you steer."); MoveShipHud = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Ship HUD", "Move ship HUD", true, "Moves the sail and rudder panel to the position below. Off leaves it where the game puts it."); ShipHudHorizontal = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Ship HUD", "Horizontal", 50, new ConfigDescription("Horizontal position on screen, in percent. 0 is left, 100 is right.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ShipHudVertical = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Ship HUD", "Vertical", 20, new ConfigDescription("Vertical position on screen, in percent. 0 is bottom, 100 is top.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); Autopilot.Active = StartMode.Value == SteeringMode.Automatic; _harmony.PatchAll(typeof(Autopilot)); _harmony.PatchAll(typeof(MapCourse)); _harmony.PatchAll(typeof(ShipCamera)); _harmony.PatchAll(typeof(ShipHud)); if (!GameAccess.SelfTest(out var problem)) { Log.LogError((object)("SteadyHelm cannot reach part of the game; setting a course on the map will not work. A game update probably renamed something. Details: " + problem)); } Log.LogInfo((object)(string.Format("{0} {1} loaded. Mode: {2}, aim: {3}, ", "SteadyHelm", "1.0.0", StartMode.Value, AimKey.Value) + $"switch: {SwitchModeKey.Value}, map: {MapCourseKey.Value}, camera: {CameraKey.Value}")); } private void OnDestroy() { _harmony.UnpatchSelf(); } private void Update() { //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_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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00c4: 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); Autopilot.TrackHelm(val); KeyboardShortcut value; int armed; if ((Object)(object)val != (Object)null) { value = MapCourseKey.Value; armed = (((KeyboardShortcut)(ref value)).IsPressed() ? 1 : 0); } else { armed = 0; } MapCourse.Armed = (byte)armed != 0; if ((Object)(object)val == (Object)null || IsTyping()) { return; } value = SwitchModeKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Autopilot.Active = !Autopilot.Active; Autopilot.HoldCurrentCourse(val); Say(Autopilot.Active ? "Steering: automatic" : "Steering: manual"); } if (Autopilot.Active) { value = AimKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed() && (Object)(object)GameCamera.instance != (Object)null) { Autopilot.SetCourse(((Component)GameCamera.instance).transform.forward); } } value = CameraKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ShipCamera.Cycle(); } } internal static void Say(string message) { if (ShowMessages.Value && (Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } } private static bool IsTyping() { if (Console.IsVisible() || TextInput.IsVisible()) { return true; } if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } } internal enum CameraView { Normal, Bow, Overhead } [HarmonyPatch] internal static class ShipCamera { private static CameraView _view; internal static void Cycle() { _view = ((_view == CameraView.Normal) ? CameraView.Bow : ((_view == CameraView.Bow) ? CameraView.Overhead : CameraView.Normal)); Plugin.Say((_view == CameraView.Normal) ? "Camera: normal" : ((_view == CameraView.Bow) ? "Camera: bow" : "Camera: overhead")); } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] [HarmonyPostfix] private static void Reposition(GameCamera __instance, float ___m_distance) { //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_0086: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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) Player localPlayer = Player.m_localPlayer; Ship val = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetControlledShip() : null); if ((Object)(object)val == (Object)null) { _view = CameraView.Normal; } else if (_view != CameraView.Normal && !((Object)(object)val.m_floatCollider == (Object)null)) { Transform transform = ((Component)val).transform; Vector3 size = val.m_floatCollider.size; ((Component)__instance).transform.position = ((_view == CameraView.Bow) ? (transform.position + transform.forward * (size.x - 0.3f) + transform.up * 3f) : (transform.position + Vector3.up * (size.z + ___m_distance + 1.3f))); } } } [HarmonyPatch] internal static class ShipHud { [HarmonyPatch(typeof(Hud), "UpdateShipHud")] [HarmonyPostfix] private static void Place(Hud __instance) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (Plugin.MoveShipHud.Value && !((Object)(object)__instance.m_shipControlsRoot == (Object)null)) { __instance.m_shipControlsRoot.transform.position = new Vector3((float)(Screen.width * Plugin.ShipHudHorizontal.Value) / 100f, (float)(Screen.height * Plugin.ShipHudVertical.Value) / 100f, 0f); } } } internal static class PluginInfo { internal const string Guid = "matheba.steadyhelm"; internal const string Name = "SteadyHelm"; internal const string Version = "1.0.0"; } }