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 Hafvisir v1.0.0
Hafvisir.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Hafvisir.Assets; using Hafvisir.Nav; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Hafvisir")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Hafvisir")] [assembly: AssemblyTitle("Hafvisir")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 Hafvisir { internal static class Recolor { private static readonly Dictionary<Texture, Texture2D> Done = new Dictionary<Texture, Texture2D>(); public static bool Possible => (int)SystemInfo.graphicsDeviceType != 4; public static Sprite Icon(Sprite source, Color tint) { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0071: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || !Possible) { return source; } Rect textureRect = source.textureRect; Texture2D val = Read((Texture)(object)source.texture, textureRect, (int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, mips: false); if ((Object)(object)val == (Object)null) { return source; } Shift(val, tint); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit); } public static void Model(GameObject root, Color tint) { //IL_0008: 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_0146: 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_0063: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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_00bc: 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) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if (!Possible) { return; } float hue = default(float); float saturation = default(float); float num = default(float); Color.RGBToHSV(tint, ref hue, ref saturation, ref num); Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (val is ParticleSystemRenderer) { continue; } Material[] sharedMaterials = val.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (!((Object)(object)sharedMaterials[j] == (Object)null)) { Material val2 = new Material(sharedMaterials[j]); Texture val3 = (val2.HasProperty("_MainTex") ? val2.GetTexture("_MainTex") : null); if ((Object)(object)val3 != (Object)null) { val2.SetTexture("_MainTex", (Texture)(object)Whole(val3, tint)); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Rehue(val2.GetColor("_Color"), hue, saturation)); } if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", Rehue(val2.GetColor("_EmissionColor"), hue, saturation)); } sharedMaterials[j] = val2; } } val.sharedMaterials = sharedMaterials; } Light[] componentsInChildren2 = root.GetComponentsInChildren<Light>(true); foreach (Light obj in componentsInChildren2) { obj.color = Rehue(obj.color, hue, saturation); } ParticleSystem[] componentsInChildren3 = root.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { MainModule main = componentsInChildren3[i].main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Rehue(((MinMaxGradient)(ref startColor)).color, hue, saturation)); } } private static Texture2D Whole(Texture source, Color tint) { //IL_0055: 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_007c: Unknown result type (might be due to invalid IL or missing references) if (Done.TryGetValue(source, out var value) && (Object)(object)value != (Object)null) { return value; } int width = Mathf.Min(source.width, 512); int height = Mathf.Min(source.height, 512); Texture2D val = Read(source, new Rect(0f, 0f, (float)source.width, (float)source.height), width, height, mips: true); if ((Object)(object)val == (Object)null) { return (Texture2D)(object)((source is Texture2D) ? source : null); } Shift(val, tint); ((Texture)val).wrapMode = source.wrapMode; Done[source] = val; return val; } private static Texture2D Read(Texture source, Rect part, int width, int height, bool mips) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; try { Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((Rect)(ref part)).width / (float)source.width, ((Rect)(ref part)).height / (float)source.height); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(((Rect)(ref part)).x / (float)source.width, ((Rect)(ref part)).y / (float)source.height); Graphics.Blit(source, temporary, val, val2); RenderTexture.active = temporary; Texture2D val3 = new Texture2D(width, height, (TextureFormat)4, mips); val3.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0); val3.Apply(mips); return val3; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not recolour " + ((Object)source).name + ": " + ex.Message)); return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static void Shift(Texture2D texture, Color tint) { //IL_0000: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0062: Unknown result type (might be due to invalid IL or missing references) float hue = default(float); float saturation = default(float); float num = default(float); Color.RGBToHSV(tint, ref hue, ref saturation, ref num); Color32[] pixels = texture.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { if (pixels[i].a != 0) { Color val = Rehue(Color32.op_Implicit(pixels[i]), hue, saturation); val.a = (float)(int)pixels[i].a / 255f; pixels[i] = Color32.op_Implicit(val); } } texture.SetPixels32(pixels); texture.Apply(((Texture)texture).mipmapCount > 1); } private static Color Rehue(Color colour, float hue, float saturation) { //IL_0000: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(colour, ref num, ref num2, ref num3); Color result = Color.HSVToRGB(hue, Mathf.Clamp01(saturation * (0.55f + 0.45f * num2)), num3, true); result.a = colour.a; return result; } } internal enum PilotState { Idle, Plotted, Sailing, Paused } internal static class Autopilot { public static readonly int StateKey = StringExtensionMethods.GetStableHashCode("hafvisir_state"); public static readonly int RemainingKey = StringExtensionMethods.GetStableHashCode("hafvisir_remaining"); private const float ScanInterval = 0.25f; private const int ScanBudget = 320; private const float MastHeight = 12f; private const float StuckSeconds = 8f; private const float StuckGrace = 12f; private const float BackMinSeconds = 3f; private const float BackMaxSeconds = 16f; private static Ship _ship; private static float _burnLeft; private static float _extraThrust; private static float _scanTimer; private static float _claimTimer; private static float _stuckTimer; private static bool _backing; private static float _backTimer; private static float _backStill; private static float _backCooldown; private static float _replanAt; private static bool _replanQueued; private static float _zdoTimer; private static int _solidMask; private static byte[] _scanned; private static float _slowScanTimer; private static float _loadedAhead = 240f; private static float _noProgress; private static float _markError; private static Vector3 _markPos; private static bool _marked; private static bool _assist; private static int _assistCount; private static Vector3 _assistPos; private static float _assistTime; private const float AssistAfter = 8f; private const float AssistMax = 30f; private const float GiveUpSeconds = 50f; private const float RoomToAvoid = 24f; private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[12]; private static float _trawled; private static float _baitNotice; private static readonly Random NetChance = new Random(); private static Ship _settleShip; private static float _settleUntil; private const float SmallObstacle = 5f; private static readonly List<Collider> Ghosted = new List<Collider>(); private static Collider[] _hullColliders; private static Ship _hullOwner; private static float _hullTimer; private static int _smallMask; public static PilotState State { get; private set; } public static Route Route { get; private set; } public static Vector3 Destination { get; private set; } public static string DestinationName { get; private set; } public static bool Planning { get; private set; } public static float Progress { get; private set; } public static string Problem { get; private set; } public static string Warning { get; private set; } public static Fuel Burning { get; private set; } public static bool Backing => _backing; public static float Remaining { get { if (Route == null) { return 0f; } return Mathf.Max(0f, Route.Length - Progress); } } public static void Reset() { State = PilotState.Idle; Route = null; Planning = false; Problem = null; Burning = null; Warning = null; _ship = null; _scanned = null; _burnLeft = 0f; } public static void SetDestination(Vector3 point, string name) { //IL_004f: 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_0054: 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; if ((Object)(object)localPlayer == (Object)null || !WorldNav.Ready) { return; } Ship ship = CurrentShip(localPlayer); Vector3 val = (((Object)(object)ship != (Object)null) ? ((Component)ship).transform.position : ((Component)localPlayer).transform.position); Destination = point; DestinationName = name; Planning = true; Problem = null; bool aboard = (Object)(object)ship != (Object)null; WorldNav.RequestRoute(val, point, HullClearance(ship), !aboard, delegate(Route route, RouteFailure failure) { Planning = false; Route = route; Progress = 0f; Warning = Tightness(route, ship); if (route == null) { Publish(PilotState.Idle); State = PilotState.Idle; Problem = Explain(failure, aboard); Notify(Problem); } else if (State == PilotState.Idle) { State = PilotState.Plotted; } }); } private static string Explain(RouteFailure failure, bool aboard) { switch (failure) { case RouteFailure.NoWaterNearStart: return "No sailable water near you"; case RouteFailure.NoWaterNearGoal: return "No sailable water near that spot"; case RouteFailure.Blocked: return "No clear route: obstacles are in the way. Steer to open water and try again"; case RouteFailure.NotConnected: if (!aboard) { return "No sea passage reaches that spot from here"; } return "This water is landlocked: no passage from here to there"; default: return "No sea route there"; } } public static void ClearCourse() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) RestoreHull(); if (State == PilotState.Sailing && (Object)(object)_ship != (Object)null && _ship.IsOwner()) { _ship.m_speed = (Speed)0; SettleDown(_ship); } Publish(PilotState.Idle); State = PilotState.Idle; Route = null; Planning = false; Problem = null; Warning = null; } private static string Tightness(Route route, Ship ship) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (route == null || (Object)(object)ship == (Object)null || (Object)(object)ship.m_floatCollider == (Object)null || WorldNav.Grid == null) { return null; } float num = ship.m_floatCollider.size.x * 0.5f + 4f; float num2 = 0f; for (float num3 = 0f; num3 < route.Length; num3 += 8f) { route.PointAt(num3, out var x, out var z); if (WorldNav.Grid.ClearAt(x, z) <= num) { num2 += 8f; } } if (!(num2 >= 16f)) { return null; } return "Tight passage: " + UIKit.Distance(num2) + " of this route leaves little room for this ship"; } public static void Toggle() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.GetControlledShip() == (Object)null) { if (State != PilotState.Idle && (Object)(object)CurrentShip(localPlayer) != (Object)null) { Notify("Hold the rudder to engage or pause Hafvisir"); } } else if (State == PilotState.Sailing) { Pause("Hafvisir paused"); } else { Engage(); } } public static void Engage() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (Route == null) { Notify(Planning ? "The route is still being calculated" : "No route set. Open the chart and click a destination."); return; } Ship controlledShip = localPlayer.GetControlledShip(); if ((Object)(object)controlledShip == (Object)null) { Notify("Hold the rudder to engage Hafvisir"); return; } if (Fuels.Next(Hold(controlledShip), out var _) == null && _burnLeft <= 0f) { Notify("No fuel in the ship's storage"); return; } if ((Object)(object)controlledShip != (Object)(object)_ship) { Burning = null; _burnLeft = 0f; } _ship = controlledShip; _stuckTimer = -12f; _noProgress = 0f; _marked = false; _assist = false; _assistCount = 0; Bridges.Reset(); _backing = false; _backCooldown = 0f; _scanTimer = 0f; _extraThrust = 0f; State = PilotState.Sailing; _settleShip = null; WorldNav.ForgetGuesses(); controlledShip.m_nview.ClaimOwnership(); Replan(0f); Notify((Warning != null) ? "Hafvisir engaged. Tight passage ahead: it will go slowly" : "Hafvisir engaged"); } public static void Pause(string message) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (State == PilotState.Sailing) { State = PilotState.Paused; _backing = false; RestoreHull(); if ((Object)(object)_ship != (Object)null && _ship.IsOwner()) { _ship.m_speed = (Speed)0; SettleDown(_ship); } Publish(PilotState.Paused); if (message != null) { Notify(message); } } } public static void ReleaseToPlayer() { _settleShip = null; WorldNav.ForgetGuesses(); } public static void Validate() { if (State == PilotState.Sailing && (Object)(object)_ship == (Object)null) { State = PilotState.Paused; } } public static Ship CurrentShip(Player player) { Ship val = player.GetControlledShip(); if ((Object)(object)val == (Object)null) { val = ((Character)player).GetStandingOnShip(); } if ((Object)(object)val == (Object)null) { val = Ship.GetLocalShip(); } Fuels.SetShip(val); return val; } public static Inventory Hold(Ship ship) { if ((Object)(object)ship == (Object)null) { return null; } Container componentInChildren = ((Component)ship).GetComponentInChildren<Container>(); if (!((Object)(object)componentInChildren != (Object)null)) { return null; } return componentInChildren.GetInventory(); } public static Fuel PlanningFuel(Ship ship) { if (State == PilotState.Sailing && Burning != null && _burnLeft > 0f) { return Burning; } ItemData stack; return Fuels.Next(Hold(ship), out stack) ?? Fuels.All[0]; } public static bool EngineActive(Ship ship) { if (State == PilotState.Sailing && (Object)(object)ship == (Object)(object)_ship && Burning != null && _burnLeft > 0f) { return !_backing; } return false; } public static bool Controls(Ship ship) { if (State == PilotState.Sailing) { return (Object)(object)ship == (Object)(object)_ship; } return false; } private static float HullClearance(Ship ship) { return Fleet.HullClearance(ship); } public static void Drive(Ship ship, float dt) { //IL_006e: 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_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_0099: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Unknown result type (might be due to invalid IL or missing references) //IL_0896: Unknown result type (might be due to invalid IL or missing references) //IL_0899: Unknown result type (might be due to invalid IL or missing references) //IL_08c7: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0909: Unknown result type (might be due to invalid IL or missing references) //IL_090b: Unknown result type (might be due to invalid IL or missing references) //IL_06cc: Unknown result type (might be due to invalid IL or missing references) //IL_06d1: Unknown result type (might be due to invalid IL or missing references) //IL_06d9: Unknown result type (might be due to invalid IL or missing references) //IL_06e6: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06fa: Unknown result type (might be due to invalid IL or missing references) //IL_0712: Unknown result type (might be due to invalid IL or missing references) //IL_0969: Unknown result type (might be due to invalid IL or missing references) //IL_096b: Unknown result type (might be due to invalid IL or missing references) //IL_0947: Unknown result type (might be due to invalid IL or missing references) //IL_0949: Unknown result type (might be due to invalid IL or missing references) //IL_0990: Unknown result type (might be due to invalid IL or missing references) //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_09b9: Unknown result type (might be due to invalid IL or missing references) //IL_09bc: Invalid comparison between Unknown and I4 //IL_098d: Unknown result type (might be due to invalid IL or missing references) //IL_0981: Unknown result type (might be due to invalid IL or missing references) //IL_0935: Unknown result type (might be due to invalid IL or missing references) //IL_0a3d: Unknown result type (might be due to invalid IL or missing references) //IL_0a15: Unknown result type (might be due to invalid IL or missing references) //IL_0a16: Unknown result type (might be due to invalid IL or missing references) //IL_0a31: Unknown result type (might be due to invalid IL or missing references) //IL_0752: Unknown result type (might be due to invalid IL or missing references) //IL_076c: Unknown result type (might be due to invalid IL or missing references) //IL_0a61: Unknown result type (might be due to invalid IL or missing references) //IL_0a64: Invalid comparison between Unknown and I4 //IL_0a66: Unknown result type (might be due to invalid IL or missing references) //IL_0a69: Invalid comparison between Unknown and I4 //IL_0b05: Unknown result type (might be due to invalid IL or missing references) //IL_0ac7: Unknown result type (might be due to invalid IL or missing references) //IL_0ae0: Unknown result type (might be due to invalid IL or missing references) //IL_0af9: Unknown result type (might be due to invalid IL or missing references) //IL_0b9b: Unknown result type (might be due to invalid IL or missing references) //IL_0b9c: Unknown result type (might be due to invalid IL or missing references) //IL_0b9f: Unknown result type (might be due to invalid IL or missing references) //IL_0ba4: Unknown result type (might be due to invalid IL or missing references) //IL_0ba9: Unknown result type (might be due to invalid IL or missing references) //IL_0bae: Unknown result type (might be due to invalid IL or missing references) //IL_0baf: Unknown result type (might be due to invalid IL or missing references) //IL_0bb6: Unknown result type (might be due to invalid IL or missing references) //IL_0bbb: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !ship.IsPlayerInBoat(localPlayer)) { Pause("Hafvisir paused: no one aboard"); } else { if (!WorldNav.Ready || Route == null) { return; } if (!ship.IsOwner()) { _claimTimer -= dt; if (_claimTimer <= 0f) { _claimTimer = 1f; ship.m_nview.ClaimOwnership(); } return; } Vector3 position = ((Component)ship).transform.position; Vector3 forward = ((Component)ship).transform.forward; forward.y = 0f; ((Vector3)(ref forward)).Normalize(); float num = Vector3.Dot(ship.m_body.linearVelocity, forward); if (!BurnFuel(ship, dt)) { return; } Progress = Route.Project(position.x, position.z, Progress, 120f + Mathf.Abs(num) * 4f, out var offCourse); float num2 = Route.Length - Progress; if (num2 <= Plugin.ArrivalRadius.Value) { Arrive(ship); return; } NavGrid grid = WorldNav.Grid; float num3 = HullClearance(ship); _scanTimer -= dt; if (_scanTimer <= 0f) { _scanTimer = 0.25f; Scan(ship, position, forward, Mathf.Clamp(Mathf.Abs(num) * 7f, 80f, 200f)); _loadedAhead = LoadedAhead(240f); if (offCourse > 60f) { _replanQueued = true; } } if (_replanQueued && Time.time >= _replanAt) { Replan(1.5f); } float num4 = grid.ClearAt(position.x, position.z); float num5 = Mathf.Clamp(Mathf.Min(Mathf.Abs(num) * 3.5f, Mathf.Max(num4 * 0.7f, Mathf.Abs(num) * 2f)), 14f, 70f); Route.PointAt(Progress + num5, out var x, out var z); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x - position.x, 0f, z - position.z); float num6 = Vector3.SignedAngle(forward, val, Vector3.up); float num7 = ship.m_body.angularVelocity.y * 57.29578f; bool flag = ship.HaveControllingPlayer(); Vector3 val2 = position - _markPos; val2.y = 0f; if (!_marked || ((Vector3)(ref val2)).sqrMagnitude > 144f || Mathf.Abs(num6) < _markError - 20f) { _marked = true; _markPos = position; _markError = Mathf.Abs(num6); _noProgress = 0f; } else { _noProgress += dt; } if (Bridges.Ahead < 80f) { _noProgress = 0f; _stuckTimer = Mathf.Min(_stuckTimer, 0f); } bool flag2 = Mathf.Abs(num6) > 60f && Mathf.Abs(num) < 3f && Room(grid, position, forward, num3, 70f) < num3 + 28f && grid.ClearAt(position.x, position.z) < 45f; if (!_assist && !Planning && (_noProgress > 8f || flag2)) { Vector3 val3 = position - _assistPos; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude > 225f) { _assistCount = 0; _assistPos = position; } if (++_assistCount > 3) { _assistCount = 0; Problem = "No room to manoeuvre here"; Pause("Hafvisir paused: no room to manoeuvre here. Steer to wider water and engage again"); return; } _assist = true; _assistTime = 0f; _backing = false; Notify("Hafvisir: working clear"); } if (_assist) { if (CastOff(ship, position, offCourse, dt)) { PublishTick(dt, num2); return; } _assist = false; _noProgress = 0f; _marked = false; _stuckTimer = -6f; } if (_noProgress > 50f) { _noProgress = 0f; Problem = "No room to manoeuvre here"; Pause("Hafvisir paused: no room to manoeuvre here. Steer to wider water and engage again"); _assist = false; return; } float num8 = Room(grid, position, forward, num3, 70f); float num9 = Room(grid, position, -forward, num3, 50f); float halfBeam = (((Object)(object)ship.m_floatCollider != (Object)null) ? (ship.m_floatCollider.size.x * 0.5f) : 2.5f); float num10 = (((Object)(object)ship.m_floatCollider != (Object)null) ? (ship.m_floatCollider.size.z * 0.5f) : (num3 - 3f)); Bridges.Tick(ship, Route, Progress, halfBeam, num10, dt); if (Bridges.Barred) { Problem = "A closed drawbridge is in the way"; Pause("Hafvisir paused: a closed drawbridge is in the way and cannot be raised from here"); return; } bool flag3 = num10 > 10f; if (flag3 && num8 < 16f) { num8 = Mathf.Max(num8, Probe(position, forward, num10, halfBeam)); } if (flag3 && num9 < 16f) { num9 = Mathf.Max(num9, Probe(position, -forward, num10, halfBeam)); } _backCooldown -= dt; if (!_backing && flag && _backCooldown <= 0f && Mathf.Abs(num) < 3f && Mathf.Abs(num6) > 75f && num8 < num3 + 28f && num9 > (flag3 ? 10f : (num3 + 8f))) { StartBacking(); } if (_backing) { _backTimer += dt; _backStill = ((Mathf.Abs(num) < 0.3f) ? (_backStill + dt) : 0f); bool flag4 = Mathf.Abs(num6) < 35f && _backTimer > 3f; bool flag5 = num9 < (flag3 ? 5f : (num3 + 2f)) && _backTimer > 3f; if (_backStill > 5f) { for (float num11 = num3 - 2f; num11 <= num3 + 8f; num11 += 5f) { WorldNav.MarkBlocked(position - forward * num11, persist: false); } } if (!(flag4 || flag5) && flag && !(_backTimer > 16f) && !(_backStill > 5f)) { ship.m_speed = (Speed)1; float num12 = (flag3 ? 0.65f : 1f); SetRudder(ship, (num6 > 0f) ? (0f - num12) : num12, dt); if (flag3 && num < -1f) { ship.m_body.AddForce(forward * (Mathf.Min(-1f - num, 2f) * 2f * dt), (ForceMode)2); } PublishTick(dt, num2); return; } _backing = false; _backCooldown = 5f; _stuckTimer = -6f; if (flag3 && num < 0f) { Vector3 linearVelocity = ship.m_body.linearVelocity; ship.m_body.linearVelocity = new Vector3(linearVelocity.x * 0.3f, linearVelocity.y, linearVelocity.z * 0.3f); } Replan(0f); } float num13 = num4; float num14 = Mathf.Max(64f, Mathf.Abs(num) * 9f); for (float num15 = 16f; num15 <= num14; num15 += 16f) { Route.PointAt(Progress + num15, out var x2, out var z2); num13 = Mathf.Min(num13, grid.ClearAt(x2, z2)); } float num16 = 6f + num13 * 0.22f; num16 = Mathf.Min(num16, Mathf.Max(1.5f, num2 * 0.11f)); num16 = Mathf.Min(num16, Mathf.Max(5f, num8 * 0.3f)); num16 = Mathf.Min(num16, 8f + _loadedAhead * 0.26f); if (Bridges.Ahead < float.MaxValue) { num16 = Mathf.Min(num16, Mathf.Max(0f, (Bridges.Ahead - num10 - 14f) * 0.3f)); } if (Mathf.Abs(num6) > 25f) { num16 = Mathf.Min(num16, 9f); } Speed val4 = (Speed)(flag ? 2 : 3); Speed val5 = (Speed)4; if (Mathf.Abs(num6) > 30f || num13 < 36f || num2 < 90f || num > num16 * 1.15f) { val5 = (Speed)3; } bool flag6 = num4 >= 45f && num8 >= 55f; if ((Mathf.Abs(num6) > 70f && !flag6) || num2 < 40f || num > num16 * 1.6f) { val5 = val4; } if (num13 < num3 + 4f) { if (flag3 && Mathf.Abs(num6) < 25f && num8 >= 16f) { val5 = (Speed)3; num16 = Mathf.Min(num16, 3.5f); } else { val5 = val4; } } if (num8 < Mathf.Max(14f, num * 3f) - num3 * 0.5f) { val5 = val4; } if (num > num16 * 1.5f && num > 12f) { val5 = (Speed)0; } if (num16 < 0.8f) { val5 = (Speed)0; } ship.m_speed = val5; float num17 = Mathf.Clamp(num6 / 35f - num7 / 60f, -1f, 1f); if ((int)val5 == 2 && flag3) { float num18 = ((num8 < 8f) ? 1f : ((_noProgress > 10f) ? 0.4f : 0.75f)); num17 = Mathf.Clamp(num17, 0f - num18, num18); } SetRudder(ship, num17, dt); if (num > num16 + 0.6f) { ship.m_body.AddForce(-forward * (Mathf.Min(num - num16, 4f) * 0.9f * dt), (ForceMode)2); } SoftHull(ship, position, num, num3, dt); float num19 = ((Burning != null) ? Burning.Power : 0f); float num20 = (((int)val5 == 4) ? 1f : (((int)val5 == 3) ? 0.5f : 0f)); float num21 = ((num < num16) ? (Mathf.Max(0f, num19 - 1f) * num20) : 0f); _extraThrust = Mathf.MoveTowards(_extraThrust, num21, dt * 1.5f); if (_extraThrust > 0.001f && position.y < WorldNav.WaterLevel + 2f) { ship.m_body.AddForce(forward * (_extraThrust * ship.m_sailForceFactor * ship.m_body.mass), (ForceMode)1); } Trawl(ship, position, num, dt); if (Burning != null && num > 2f) { Fuels.Learn(Burning, num, dt * 0.01f); } if (Mathf.Abs(num) < 0.5f && Mathf.Abs(num7) < 2f) { _stuckTimer += dt; } else if (_stuckTimer > 0f) { _stuckTimer = 0f; } if (_stuckTimer > 8f) { _stuckTimer = 0f; for (float num22 = num3 - 2f; num22 <= num3 + 14f; num22 += 6f) { for (float num23 = -6f; num23 <= 6f; num23 += 6f) { WorldNav.MarkBlocked(position + forward * num22 + Vector3.Cross(Vector3.up, forward) * num23, persist: false); } } if (flag) { StartBacking(); Notify("Hafvisir: reversing clear of an obstacle"); } else { Replan(0f); } } PublishTick(dt, num2); } } private static float LoadedAhead(float max) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num2 = default(float); for (float num = 24f; num <= max && !(Progress + num > Route.Length); num += 24f) { Route.PointAt(Progress + num, out var x, out var z); if (!Heightmap.GetHeight(new Vector3(x, 0f, z), ref num2)) { return num - 24f; } } return max; } private static void StartBacking() { _backing = true; _backTimer = 0f; _backStill = 0f; _extraThrust = 0f; } private static float Room(NavGrid grid, Vector3 pos, Vector3 dir, float hull, float max) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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) float num = hull - 3f; for (float num2 = num; num2 <= num + max; num2 += 4f) { if (grid.ClearAt(pos.x + dir.x * num2, pos.z + dir.z * num2) == 0f) { return num2 - num; } } return max; } private static bool CastOff(Ship ship, Vector3 pos, float off, float dt) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) _assistTime += dt; Route.PointAt(Progress + 4f, out var x, out var z); Route.PointAt(Mathf.Min(Route.Length, Progress + 22f), out var x2, out var z2); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x2 - x, 0f, z2 - z); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return false; } ((Vector3)(ref val)).Normalize(); GhostHull.Hold(ship, 1.5f); Rigidbody body = ship.m_body; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(x - pos.x, 0f, z - pos.z); float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude > 0.05f) { body.position += val2 / magnitude * Mathf.Min(magnitude, 2.5f * dt); } Quaternion val3 = body.rotation; Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles; val3 = Quaternion.LookRotation(val, Vector3.up); float y = ((Quaternion)(ref val3)).eulerAngles.y; float num = Mathf.MoveTowardsAngle(eulerAngles.y, y, 28f * dt); body.rotation = Quaternion.Euler(eulerAngles.x, num, eulerAngles.z); body.linearVelocity = new Vector3(0f, body.linearVelocity.y, 0f); Vector3 angularVelocity = body.angularVelocity; angularVelocity.y = 0f; body.angularVelocity = angularVelocity; ship.m_speed = (Speed)0; ship.m_rudderValue = 0f; ship.m_rudder = 0f; if (!(off < 3f) || !(Mathf.Abs(Mathf.DeltaAngle(num, y)) < 10f) || !(WorldNav.Grid.ClearAt(pos.x, pos.z) > 0f)) { return _assistTime < 30f; } return false; } private static float Probe(Vector3 pos, Vector3 dir, float halfLength, float halfBeam) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0067: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) if (_solidMask == 0) { _solidMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); } float waterLevel = WorldNav.WaterLevel; Vector3 val = Vector3.Cross(Vector3.up, dir); for (float num = 2f; num <= 16f; num += 3.5f) { for (int i = -1; i <= 1; i++) { Vector3 origin = pos + dir * (halfLength + num) + val * ((float)i * halfBeam * 0.8f); origin.y = waterLevel + 12f; if (Obstructed(origin, waterLevel - 1.6f, tight: true)) { return num - 2f; } } } return 16f; } private static void SetRudder(Ship ship, float target, float dt) { float num = Mathf.Max(0.5f, ship.m_rudderSpeed) * 1.5f * dt; ship.m_rudderValue = Mathf.MoveTowards(ship.m_rudderValue, target, num); ship.m_rudder = Mathf.Clamp(target - ship.m_rudderValue, -1f, 1f); } private static void Trawl(Ship ship, Vector3 pos, float speed, float dt) { //IL_007e: 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) if (speed <= 0f) { return; } _trawled += speed * dt; float num = Mathf.Max(50f, Plugin.MetresPerFish.Value); if (_trawled < num) { return; } _trawled -= num; Container componentInChildren = ((Component)ship).GetComponentInChildren<Container>(); Inventory hold = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.GetInventory() : null); if (!Modules.Has(hold, "Fishing Nets") || componentInChildren.IsInUse() || WorldGenerator.instance == null) { return; } bool lacking; GameObject val = Modules.Catch(hold, WorldGenerator.instance.GetBiome(pos), NetChance, out lacking); if ((Object)(object)val == (Object)null) { if (lacking && Time.time > _baitNotice && (Object)(object)Player.m_localPlayer != (Object)null) { _baitNotice = Time.time + 180f; ((Character)Player.m_localPlayer).Message((MessageType)1, "Nets: no bait aboard for these waters", 0, (Sprite)null, false); } return; } Player localPlayer = Player.m_localPlayer; ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)localPlayer != (Object)null && (Object)(object)component != (Object)null) { ((Character)localPlayer).Message((MessageType)1, "Nets: " + Localization.instance.Localize(component.m_itemData.m_shared.m_name), 1, component.m_itemData.GetIcon(), false); } } private static bool BurnFuel(Ship ship, float dt) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected I4, but got Unknown float num = 0f; Speed speed = ship.m_speed; switch (speed - 1) { case 3: num = 1f; break; case 2: num = 0.6f; break; case 1: num = 0.3f; break; case 0: num = 0.3f; break; } if (Burning != null) { _burnLeft -= dt * num / (Burning.Seconds * Modules.Stretch(Modules.Has(Hold(ship), "Fuel Regulator"))); } if (_burnLeft > 0f) { return true; } Container componentInChildren = ((Component)ship).GetComponentInChildren<Container>(); Inventory val = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.GetInventory() : null); ItemData stack; Fuel fuel = Fuels.Next(val, out stack); if (fuel == null) { _burnLeft = 0f; Burning = null; Pause("Hafvisir paused: out of fuel"); return false; } if (componentInChildren.IsInUse()) { return true; } Burning = fuel; _burnLeft = 1f; val.RemoveItem(stack, 1); return true; } private static void Arrive(Ship ship) { //IL_0006: 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) Bridges.Lower(((Component)ship).transform.position, 12f, all: true); ship.m_speed = (Speed)0; ship.m_rudderValue = 0f; RestoreHull(); SettleDown(ship); string destinationName = DestinationName; Publish(PilotState.Idle); State = PilotState.Idle; Route = null; Notify(string.IsNullOrEmpty(destinationName) ? "Arrived at destination" : ("Arrived at " + destinationName)); } private static void SettleDown(Ship ship) { _settleShip = ship; _settleUntil = Time.time + 8f; } public static void Settle(Ship ship, float dt) { //IL_002b: 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_005e: 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_006c: 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) if (!((Object)(object)ship != (Object)(object)_settleShip)) { if (Time.time > _settleUntil || State == PilotState.Sailing || !ship.IsOwner() || (int)ship.m_speed != 0) { _settleShip = null; return; } Vector3 linearVelocity = ship.m_body.linearVelocity; float num = Mathf.Clamp01(1f - 1.2f * dt); ship.m_body.linearVelocity = new Vector3(linearVelocity.x * num, linearVelocity.y, linearVelocity.z * num); } } private static void SoftHull(Ship ship, Vector3 pos, float speed, float hull, float dt) { //IL_013a: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) _hullTimer -= dt; if (_hullTimer > 0f) { return; } _hullTimer = 0.3f; Collider[] componentsInChildren; if ((Object)(object)_hullOwner != (Object)(object)ship) { RestoreHull(); _hullOwner = ship; List<Collider> list = new List<Collider>(); componentsInChildren = ((Component)ship).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if (!val.isTrigger) { list.Add(val); } } _hullColliders = list.ToArray(); } if (_smallMask == 0) { _smallMask = LayerMask.GetMask(new string[3] { "static_solid", "Default", "Default_small" }); } Bounds bounds; for (int num = Ghosted.Count - 1; num >= 0; num--) { Collider val2 = Ghosted[num]; if ((Object)(object)val2 != (Object)null) { bounds = val2.bounds; Vector3 val3 = ((Bounds)(ref bounds)).center - pos; if (((Vector3)(ref val3)).sqrMagnitude < (hull + 18f) * (hull + 18f)) { continue; } } Ignore(val2, ignore: false); Ghosted.RemoveAt(num); } bool flag = Mathf.Abs(speed) <= 5f; NavGrid grid = WorldNav.Grid; componentsInChildren = Physics.OverlapSphere(pos, hull + 8f, _smallMask, (QueryTriggerInteraction)1); foreach (Collider val4 in componentsInChildren) { if (!Ghosted.Contains(val4) && Small(val4)) { bounds = val4.bounds; Vector3 center = ((Bounds)(ref bounds)).center; if (flag || !(grid.ClearAt(center.x, center.z) >= 24f)) { Ignore(val4, ignore: true); Ghosted.Add(val4); } } } } private static bool Small(Collider c) { //IL_0019: 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_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_0027: 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_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)c.attachedRigidbody != (Object)null || c is TerrainCollider) { return false; } Bounds bounds = c.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (Mathf.Max(size.x, Mathf.Max(size.y, size.z)) > 5f) { return false; } if ((Object)(object)((Component)c).GetComponentInParent<Piece>() == (Object)null) { return (Object)(object)((Component)c).GetComponentInParent<Heightmap>() == (Object)null; } return false; } private static void Ignore(Collider obstacle, bool ignore) { if ((Object)(object)obstacle == (Object)null || _hullColliders == null) { return; } Collider[] hullColliders = _hullColliders; foreach (Collider val in hullColliders) { if ((Object)(object)val != (Object)null) { Physics.IgnoreCollision(val, obstacle, ignore); } } } private static void RestoreHull() { foreach (Collider item in Ghosted) { Ignore(item, ignore: false); } Ghosted.Clear(); } private static void Scan(Ship ship, Vector3 pos, Vector3 forward, float range) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0122: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) NavGrid grid = WorldNav.Grid; if (_scanned == null || _scanned.Length != grid.Clear.Length) { _scanned = new byte[grid.Clear.Length]; } if (_solidMask == 0) { _solidMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); } float waterLevel = WorldNav.WaterLevel; float limit = waterLevel - Plugin.MinDepth.Value; float num = HullClearance(ship); Vector3 val = Vector3.Cross(Vector3.up, forward); float cell = grid.Cell; int num2 = 320; bool flag = false; float num9 = default(float); for (float num3 = 0f - (num + 34f); num3 <= range; num3 += cell * 0.75f) { if (num2 <= 0) { break; } float num4 = ((num3 < num + 34f) ? (num + 34f) : (14f + num3 * 0.4f)); for (float num5 = 0f - num4; num5 <= num4; num5 += cell * 0.75f) { if (num2 <= 0) { break; } if (Mathf.Abs(num3) < num - 2f && Mathf.Abs(num5) < 5f) { continue; } Vector3 val2 = pos + forward * num3 + val * num5; int num6 = grid.Index(val2.x, val2.z); byte b = (byte)((!(num3 <= 40f)) ? 1u : 2u); if (_scanned[num6] >= b || grid.Clear[num6] == 0) { continue; } float num7 = grid.CellX(num6 % grid.Size); float num8 = grid.CellZ(num6 / grid.Size); if (!Heightmap.GetHeight(new Vector3(num7, 0f, num8), ref num9)) { continue; } _scanned[num6] = b; for (int i = 0; i < 5; i++) { float num10; switch (i) { default: num10 = 2.5f; break; case 1: case 2: num10 = -2.5f; break; case 0: num10 = 0f; break; } float num11 = num10; float num12; switch (i) { default: num12 = 2.5f; break; case 1: case 3: num12 = -2.5f; break; case 0: num12 = 0f; break; } float num13 = num12; num2--; if (Obstructed(new Vector3(num7 + num11, waterLevel + 12f, num8 + num13), limit, (float)(int)grid.Clear[num6] < 24f)) { flag |= WorldNav.MarkBlocked(new Vector3(num7, 0f, num8)); break; } } } } _slowScanTimer -= 0.25f; if (_slowScanTimer <= 0f) { _slowScanTimer = 2f; Leviathan[] array = Object.FindObjectsByType<Leviathan>((FindObjectsSortMode)0); Vector3 val3; for (int j = 0; j < array.Length; j++) { Vector3 position = ((Component)array[j]).transform.position; val3 = position - pos; if (!(((Vector3)(ref val3)).sqrMagnitude > 62500f)) { flag |= MarkDisc(position, 32f, cell, persist: true); } } foreach (Ship instance in Ship.Instances) { Ship val4 = instance; if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)ship)) { Vector3 position2 = ((Component)val4).transform.position; val3 = position2 - pos; if (!(((Vector3)(ref val3)).sqrMagnitude > 40000f)) { flag |= MarkDisc(position2, HullClearance(val4), cell, persist: false); } } } } if (flag && CourseObstructed(grid, num)) { _replanQueued = true; } } private static bool MarkDisc(Vector3 centre, float radius, float cell, bool persist) { //IL_0019: 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_002e: Unknown result type (might be due to invalid IL or missing references) bool flag = false; for (float num = 0f - radius; num <= radius; num += cell) { for (float num2 = 0f - radius; num2 <= radius; num2 += cell) { if (num * num + num2 * num2 <= radius * radius) { flag |= WorldNav.MarkBlocked(new Vector3(centre.x + num, 0f, centre.z + num2), persist); } } } return flag; } private static bool Obstructed(Vector3 origin, float limit, bool tight) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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) int num = Physics.RaycastNonAlloc(origin, Vector3.down, Hits, origin.y - limit, _solidMask, (QueryTriggerInteraction)1); for (int i = 0; i < num; i++) { Collider collider = ((RaycastHit)(ref Hits[i])).collider; Rigidbody attachedRigidbody = collider.attachedRigidbody; if ((Object)(object)attachedRigidbody != (Object)null) { if ((Object)(object)((Component)attachedRigidbody).GetComponent<Leviathan>() != (Object)null) { return true; } } else if ((!tight || !Small(collider)) && !BridgePass.Covers(collider)) { return true; } } return false; } private static bool CourseObstructed(NavGrid grid, float hull) { for (float num = 0f; num <= 300f && !(Progress + num > Route.Length); num += grid.Cell) { Route.PointAt(Progress + num, out var x, out var z); if (grid.ClearAt(x, z) < hull) { return true; } } return false; } private static void Replan(float cooldown) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_ship == (Object)null) { return; } _replanQueued = false; _replanAt = Time.time + cooldown; Ship ship = _ship; Planning = true; WorldNav.RequestRoute(((Component)ship).transform.position, Destination, HullClearance(ship), fromShore: false, delegate(Route route, RouteFailure failure) { Planning = false; if (route == null) { Problem = Explain(failure, aboard: true); if (State == PilotState.Sailing) { Pause(Problem); } } else { Problem = null; Route = route; Progress = 0f; _markError = 180f; Warning = Tightness(route, ship); } }); } private static void PublishTick(float dt, float remaining) { _zdoTimer -= dt; if (!(_zdoTimer > 0f)) { _zdoTimer = 1f; ZDO zDO = _ship.m_nview.GetZDO(); if (zDO != null) { zDO.Set(StateKey, 2, false); zDO.Set(RemainingKey, remaining); } } } private static void Publish(PilotState state) { if (!((Object)(object)_ship == (Object)null) && !((Object)(object)_ship.m_nview == (Object)null) && _ship.m_nview.IsValid() && _ship.m_nview.IsOwner()) { _ship.m_nview.GetZDO().Set(StateKey, (int)state, false); } } private static void Notify(string text) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } } } internal static class Bridges { private const float Reach = 160f; private const float OpenWithin = 130f; private static readonly Dictionary<Door, float> Raised = new Dictionary<Door, float>(); private static readonly Dictionary<Door, float> Used = new Dictionary<Door, float>(); private static readonly List<Door> Scratch = new List<Door>(); private static readonly Dictionary<Door, float> Heights = new Dictionary<Door, float>(); private static float _timer; private static readonly Dictionary<Door, float> Nearest = new Dictionary<Door, float>(); public static float Ahead { get; private set; } = float.MaxValue; public static bool Barred { get; private set; } public static void Reset() { Heights.Clear(); Raised.Clear(); Used.Clear(); Ahead = float.MaxValue; Barred = false; _timer = 0f; } public static void Tick(Ship ship, Route route, float progress, float halfBeam, float halfLength, float dt) { //IL_003a: 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_0069: 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_006f: 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_021a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) _timer -= dt; if (_timer > 0f) { return; } _timer = 0.5f; Ahead = float.MaxValue; Barred = false; Vector3 position = ((Component)ship).transform.position; foreach (Door drawbridge in BridgePass.Drawbridges) { if (!IsDrawbridge(drawbridge)) { continue; } Vector3 val = ((Component)drawbridge).transform.position - position; if (((Vector3)(ref val)).sqrMagnitude > 25600f || !Deck(drawbridge, out var deck)) { continue; } float value; bool flag = Heights.TryGetValue(drawbridge, out value) && Mathf.Abs(((Bounds)(ref deck)).size.y - value) > 0.04f; Heights[drawbridge] = ((Bounds)(ref deck)).size.y; Vector3 val2 = ((Component)drawbridge).transform.position - position; val2.y = 0f; if (Raised.ContainsKey(drawbridge) && flag && Vector3.Dot(val2, ((Component)ship).transform.forward) > 0f) { Ahead = Mathf.Min(Ahead, Mathf.Max(0f, ((Vector3)(ref val2)).magnitude - 4f)); } if (!Lowered(deck)) { continue; } float num = OnCourse(route, progress, deck, halfBeam + 3f); if (num < 0f) { continue; } Ahead = Mathf.Min(Ahead, num); if (!MayUse(drawbridge)) { if (num < 70f) { Barred = true; } } else { if (num > 130f || !Rested(drawbridge)) { continue; } if (!Raised.ContainsKey(drawbridge)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "Hafvisir: raising the drawbridge", 0, (Sprite)null, false); } } if (!Raised.ContainsKey(drawbridge)) { Raised[drawbridge] = ((Vector3)(ref val2)).magnitude; } Use(drawbridge); } } Lower(position, halfLength, all: false); } public static void Lower(Vector3 pos, float halfLength, bool all) { //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_004f: 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_00ce: Unknown result type (might be due to invalid IL or missing references) Scratch.Clear(); foreach (KeyValuePair<Door, float> item in Raised) { Door key = item.Key; if ((Object)(object)key == (Object)null) { Scratch.Add(key); continue; } Vector3 val = ((Component)key).transform.position - pos; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < item.Value) { Nearest[key] = magnitude; } else if (((magnitude > item.Value + 12f && magnitude > halfLength + 16f) || (all && magnitude > item.Value + 4f)) && (Rested(key) || all)) { if (Deck(key, out var deck) && !Lowered(deck)) { Use(key); } Scratch.Add(key); } } foreach (KeyValuePair<Door, float> item2 in Nearest) { Raised[item2.Key] = item2.Value; } Nearest.Clear(); foreach (Door item3 in Scratch) { Raised.Remove(item3); } } internal static bool IsDrawbridge(Door door) { if ((Object)(object)door != (Object)null && (Object)(object)door.m_nview != (Object)null && door.m_nview.IsValid()) { return Utils.GetPrefabName(((Component)door).gameObject).ToLowerInvariant().Contains("drawbridge"); } return false; } internal static bool Deck(Door door, out Bounds deck) { //IL_0001: 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_0043: Unknown result type (might be due to invalid IL or missing references) deck = default(Bounds); Rigidbody componentInChildren = ((Component)door).GetComponentInChildren<Rigidbody>(); if ((Object)(object)componentInChildren == (Object)null) { return false; } bool flag = false; Collider[] componentsInChildren = ((Component)componentInChildren).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if (!val.isTrigger && val.enabled) { if (flag) { ((Bounds)(ref deck)).Encapsulate(val.bounds); } else { deck = val.bounds; } flag = true; } } return flag; } private static bool Lowered(Bounds deck) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) return ((Bounds)(ref deck)).size.y < Mathf.Max(((Bounds)(ref deck)).size.x, ((Bounds)(ref deck)).size.z) * 0.75f; } private static float OnCourse(Route route, float progress, Bounds deck, float margin) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) for (float num = 0f; num <= 160f && !(progress + num > route.Length); num += 3f) { route.PointAt(progress + num, out var x, out var z); if (((Bounds)(ref deck)).SqrDistance(new Vector3(x, ((Bounds)(ref deck)).center.y, z)) < margin * margin) { return num; } } return -1f; } private static bool MayUse(Door door) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)door.m_keyItem != (Object)null) { return false; } if (door.m_checkGuardStone) { return PrivateArea.CheckAccess(((Component)door).transform.position, 0f, false, false); } return true; } private static bool Rested(Door door) { if (Used.TryGetValue(door, out var value)) { return Time.time > value + 8f; } return true; } private static void Use(Door door) { //IL_0020: 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) Used[door] = Time.time; Plugin.Log.LogInfo((object)$"Drawbridge at {((Component)door).transform.position.x:0},{((Component)door).transform.position.z:0} worked by the helm (was state {door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0)})"); door.m_nview.InvokeRPC("UseDoor", new object[1] { true }); } } internal static class BridgePass { private struct Gate { public Vector3 Centre; public float Radius; } private const float Frame = 4f; private static readonly List<Gate> Gates = new List<Gate>(); public static readonly List<Door> Drawbridges = new List<Door>(); private static float _timer; private static int _refresh; public static bool InGate(Vector3 point, float margin = 0f) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) foreach (Gate gate in Gates) { float num = point.x - gate.Centre.x; float num2 = point.z - gate.Centre.z; float num3 = gate.Radius + margin; if (num * num + num2 * num2 < num3 * num3) { return true; } } return false; } public static bool Covers(Collider collider) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) if (!((Object)(object)collider == (Object)null) && Gates.Count != 0) { Bounds bounds = collider.bounds; if (InGate(((Bounds)(ref bounds)).center)) { return (Object)(object)((Component)collider).GetComponentInParent<Piece>() != (Object)null; } } return false; } public static void Tick() { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) _timer -= Time.deltaTime; if (_timer > 0f) { return; } _timer = 0.5f; if (!Plugin.BridgesPassable.Value || (Object)(object)ZNetScene.instance == (Object)null || Ship.Instances.Count == 0) { Gates.Clear(); Drawbridges.Clear(); return; } if (_refresh-- <= 0) { _refresh = 5; Gates.Clear(); Drawbridges.Clear(); Door[] array = Object.FindObjectsByType<Door>((FindObjectsSortMode)0); foreach (Door val in array) { if (Bridges.IsDrawbridge(val)) { Drawbridges.Add(val); float num = 8f; if (Bridges.Deck(val, out var deck)) { num = Mathf.Max(((Bounds)(ref deck)).size.x, Mathf.Max(((Bounds)(ref deck)).size.y, ((Bounds)(ref deck)).size.z)); } Gates.Add(new Gate { Centre = ((Component)val).transform.position, Radius = num + 4f }); } } } if (Gates.Count == 0) { return; } foreach (Ship instance in Ship.Instances) { Ship val2 = instance; if ((Object)(object)val2 != (Object)null && InGate(((Component)val2).transform.position, Fleet.HullClearance(val2))) { GhostHull.Hold(val2, 1.2f); } } } } internal sealed class Module { public string Prefab; public string Name; public string Description; public string[] Templates; public Func<int> Price; public GameObject Object; public Color Tint; public string IconAsset; public string MeshAsset; } internal static class Modules { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDbAwake { private static void Postfix(ObjectDB __instance) { AddTo(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDbCopy { private static void Postfix(ObjectDB __instance) { AddTo(__instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class SceneAwake { private static void Postfix(ZNetScene __instance) { if ((Object)(object)ObjectDB.instance != (Object)null) { AddTo(ObjectDB.instance); } foreach (Module item in All) { if (!((Object)(object)item.Object == (Object)null)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)item.Object).name); if (!__instance.m_namedPrefabs.ContainsKey(stableHashCode)) { __instance.m_prefabs.Add(item.Object); __instance.m_namedPrefabs.Add(stableHashCode, item.Object); } } } } } public const string AntennaPrefab = "HafvisirAntenna"; public const string AntennaName = "Sonar Antenna"; public const string RegulatorPrefab = "HafvisirRegulator"; public const string RegulatorName = "Fuel Regulator"; public const string NetsPrefab = "HafvisirNets"; public const string NetsName = "Fishing Nets"; public static readonly List<Module> All = new List<Module> { new Module { Prefab = "HafvisirBeacon", Name = "Hafvisir Beacon", Templates = new string[2] { "Thunderstone", "SurtlingCore" }, Tint = new Color(0.25f, 1f, 0.8f), IconAsset = "icon_beacon", MeshAsset = "beacon", Price = () => Plugin.BeaconPrice.Value, Description = "Mossbeard's own make. Stow it in a ship's storage and that ship can be sent to sea with no one aboard from a Captain's Table. A ship with no crew is an insult to Aegir, the old sea jotunn. Now and then he stops one dead and keeps its fuel." }, new Module { Prefab = "HafvisirAntenna", Name = "Sonar Antenna", Templates = new string[3] { "MechanicalSpring", "DvergrNeedle", "Thunderstone" }, Tint = new Color(1f, 0.72f, 0.15f), IconAsset = "icon_antenna", MeshAsset = "antenna", Price = () => Plugin.AntennaPrice.Value, Description = "A brass aerial that sounds out the coast. While it sits in a ship's storage, everyone aboard uncovers the map much farther around the ship." }, new Module { Prefab = "HafvisirRegulator", Name = "Fuel Regulator", Templates = new string[3] { "BlackCore", "SurtlingCore", "Thunderstone" }, Tint = new Color(1f, 0.3f, 0.2f), IconAsset = "icon_regulator", MeshAsset = "regulator", Price = () => Plugin.RegulatorPrice.Value, Description = "A valve that feeds the firebox evenly. While it sits in a ship's storage, Hafvisir burns a quarter less fuel on every trip, with a crew or without." }, new Module { Prefab = "HafvisirNets", Name = "Fishing Nets", Templates = new string[3] { "LinenThread", "FishingRod", "Chain" }, Tint = new Color(0.85f, 0.6f, 0.3f), IconAsset = "icon_nets", MeshAsset = "nets", Price = () => Plugin.NetsPrice.Value, Description = "Nets trailed behind a ship. While they sit in its storage, a ship sailing under Hafvisir lands a fish every so often. The catch depends on the waters it crosses, and each fish uses up the bait it takes on a rod, which must be in the storage too." } }; private static GameObject _holder; private static readonly Dictionary<Color, Texture2D> Paints = new Dictionary<Color, Texture2D>(); private static readonly float[] Shades = new float[7] { 0.55f, 0.68f, 0.78f, 0.86f, 0.86f, 0.93f, 1f }; public static float Stretch(bool regulated) { if (!regulated) { return 1f; } return 1f / (1f - Mathf.Clamp(Plugin.RegulatorSaving.Value, 0f, 0.9f)); } public static bool Has(Inventory hold, string module) { if (hold != null) { return hold.CountItems(module, -1, true) > 0; } return false; } private static string[] Waters(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected I4, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((int)biome <= 16) { switch (biome - 1) { default: if ((int)biome != 8) { if ((int)biome != 16) { break; } return new string[1] { "Fish7" }; } return new string[2] { "Fish5", "Fish2" }; case 0: return new string[2] { "Fish1", "Fish2" }; case 1: return new string[1] { "Fish6" }; case 3: return new string[1] { "Fish2" }; case 2: break; } } else { if ((int)biome == 32) { return new string[1] { "Fish11" }; } if ((int)biome == 64) { return new string[1] { "Fish10" }; } if ((int)biome == 512) { return new string[2] { "Fish9", "Fish12" }; } } return new string[2] { "Fish3", "Fish8" }; } public static GameObject Catch(Inventory hold, Biome biome, Random chance, out bool lacking) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) lacking = false; if (hold == null || (Object)(object)ObjectDB.instance == (Object)null) { return null; } string[] array = Waters(biome); int num = ((array.Length > 1 && chance.Next(3) == 0) ? 1 : 0); int num2 = Mathf.Max(1, Plugin.BaitPerFish.Value); for (int i = 0; i < array.Length; i++) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array[(num + i) % array.Length]); if ((Object)(object)itemPrefab == (Object)null) { continue; } string text = null; if (Plugin.NetsNeedBait.Value) { Fish component = itemPrefab.GetComponent<Fish>(); if ((Object)(object)component != (Object)null && component.m_baits != null && component.m_baits.Count > 0) { foreach (BaitSetting bait in component.m_baits) { string text2 = (((Object)(object)bait.m_bait != (Object)null) ? bait.m_bait.m_itemData.m_shared.m_name : null); if (text2 != null && hold.CountItems(text2, -1, true) >= num2) { text = text2; break; } } if (text == null) { lacking = true; continue; } } } if (!hold.AddItem(itemPrefab, 1)) { lacking = false; return null; } if (text != null) { hold.RemoveItem(text, num2, -1, true); } lacking = false; return itemPrefab; } return null; } private static GameObject Build(ObjectDB db, Module module) { //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0155: 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_008e: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)module.Object != (Object)null) { return module.Object; } GameObject val = null; string[] templates = module.Templates; foreach (string name in templates) { val = db.m_items.Find((GameObject item) => (Object)(object)item != (Object)null && ((Object)item).name == name); if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { return null; } if ((Object)(object)_holder == (Object)null) { _holder = new GameObject("HafvisirPrefabs"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); } GameObject val2 = Object.Instantiate<GameObject>(val, _holder.transform); ((Object)val2).name = module.Prefab; ItemDrop component = val2.GetComponent<ItemDrop>(); component.m_itemData = component.m_itemData.Clone(); component.m_itemData.m_shared = (SharedData)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(component.m_itemData.m_shared, null); SharedData shared = component.m_itemData.m_shared; shared.m_name = module.Name; shared.m_description = module.Description; shared.m_maxStackSize = 1; shared.m_weight = 4f; shared.m_value = 0; shared.m_teleportable = true; shared.m_itemType = (ItemType)1; shared.m_maxQuality = 1; shared.m_useDurability = false; Texture2D val3 = ((module.IconAsset != null && Recolor.Possible) ? UIKit.Embedded(module.IconAsset) : null); if ((Object)(object)val3 != (Object)null) { ((Texture)val3).filterMode = (FilterMode)1; shared.m_icons = (Sprite[])(object)new Sprite[1] { Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f), 100f) }; } else if (shared.m_icons != null && shared.m_icons.Length != 0) { shared.m_icons = (Sprite[])(object)new Sprite[1] { Recolor.Icon(shared.m_icons[0], module.Tint) }; } if (module.MeshAsset == null || !Remodel(val2, module.MeshAsset)) { Recolor.Model(val2, module.Tint); } component.m_itemData.m_dropPrefab = val2; module.Object = val2; return val2; } public static GameObject Model(string asset, Material like, int layer, float glow = 1f) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Expected O, but got Unknown //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Expected O, but got Unknown //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) if (!Recolor.Possible || (Object)(object)like == (Object)null) { return null; } Stream manifestResourceStream = typeof(Modules).Assembly.GetManifestResourceStream("Hafvisir.assets." + asset + ".mesh"); if (manifestResourceStream == null) { return null; } List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<Vector2> list3 = new List<Vector2>(); List<Color> list4 = new List<Color>(); List<float> list5 = new List<float>(); List<List<int>> list6 = new List<List<int>>(); int num = 0; using (StreamReader streamReader = new StreamReader(manifestResourceStream)) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; string text; while ((text = streamReader.ReadLine()) != null) { string[] array = text.Split(new char[1] { ' ' }); if (array[0] == "c") { list4.Add(new Color(float.Parse(array[1], invariantCulture), float.Parse(array[2], invariantCulture), float.Parse(array[3], invariantCulture))); list5.Add((array.Length > 4) ? float.Parse(array[4], invariantCulture) : 0f); list6.Add(new List<int>()); num = list.Count; } else if (array[0] == "v") { list.Add(new Vector3(float.Parse(array[1], invariantCulture), float.Parse(array[2], invariantCulture), float.Parse(array[3], invariantCulture))); list2.Add(new Vector3(float.Parse(array[4], invariantCulture), float.Parse(array[5], invariantCulture), float.Parse(array[6], invariantCulture))); list3.Add((Vector2)((array.Length > 8) ? new Vector2(float.Parse(array[7], invariantCulture), float.Parse(array[8], invariantCulture)) : Vector2.zero)); } else if (array[0] == "t") { List<int> list7 = list6[list6.Count - 1]; list7.Add(num + int.Parse(array[1])); list7.Add(num + int.Parse(array[2])); list7.Add(num + int.Parse(array[3])); } } } Mesh val = new Mesh { name = "Hafvisir_" + asset }; if (list.Count > 65000) { val.indexFormat = (IndexFormat)1; } val.SetVertices(list); val.SetNormals(list2); val.SetUVs(0, list3); val.subMeshCount = list6.Count; for (int i = 0; i < list6.Count; i++) { val.SetTriangles(list6[i], i); } val.RecalculateBounds(); Material[] array2 = (Material[])(object)new Material[list4.Count]; for (int j = 0; j < array2.Length; j++) { array2[j] = new Material(like); array2[j].mainTexture = (Texture)(object)((list5[j] > 0f) ? Texture2D.whiteTexture : Paint(list4[j])); if (array2[j].HasProperty("_BumpMap")) { array2[j].SetTexture("_BumpMap", (Texture)null); } if (array2[j].HasProperty("_MetallicGlossMap")) { array2[j].SetTexture("_MetallicGlossMap", (Texture)null); } if (array2[j].HasProperty("_Color")) { array2[j].SetColor("_Color", (list5[j] > 0f) ? list4[j] : Color.white); } if (array2[j].HasProperty("_Cull")) { array2[j].SetFloat("_Cull", 0f); } if (list5[j] > 0f && array2[j].HasProperty("_EmissionColor")) { array2[j].EnableKeyword("_EMISSION"); array2[j].SetColor("_EmissionColor", list4[j] * (Mathf.Min(list5[j], 3f) * glow)); } } GameObject val2 = new GameObject("HafvisirModel") { layer = layer }; val2.AddComponent<MeshFilter>().sharedMesh = val; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = array2; return val2; } private unsafe static Texture2D Paint(Color colour) { //IL_0005: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) if (Paints.TryGetValue(colour, out var value) && (Object)(object)value != (Object)null) { return value; } Random random = new Random(((object)(*(Color*)(&colour))/*cast due to .constrained prefix*/).GetHashCode()); Color32[] array = (Color32[])(object)new Color32[256]; for (int i = 0; i < array.Length; i++) { float num = Shades[random.Next(Shades.Length)]; float num2 = (float)(random.NextDouble() - 0.5) * 0.08f; array[i] = Color32.op_Implicit(new Color(Mathf.Clamp01(colour.r * num + num2), Mathf.Clamp01(colour.g * num), Mathf.Clamp01(colour.b * num - num2), 1f)); } Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)0 }; val.SetPixels32(array); val.Apply(false); Paints[colour] = val; return val; } private static bool Remodel(GameObject prefab, string asset) { //IL_00bc: 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_010c: Unknown result type (might be due to invalid IL or missing references) MeshRenderer componentInChildren = prefab.GetComponentInChildren<MeshRenderer>(true); GameObject val = Model(asset, ((Object)(object)componentInChildren != (Object)null) ? ((Renderer)componentInChildren).sharedMaterial : null, ((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject.layer : 0); if ((Object)(object)val == (Object)null) { return false; } Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } LODGroup[] componentsInChildren2 = prefab.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Light[] componentsInChildren3 = prefab.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } ParticleSystem[] componentsInChildren4 = prefab.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { EmissionModule emission = componentsInChildren4[i].emission; ((EmissionModule)(ref emission)).enabled = false; } if (!prefab.activeSelf) { prefab.SetActive(true); } val.transform.SetParent(prefab.transform, false); val.transform.localPosition = new Vector3(0f, 0.05f, 0f); return true; } private static void AddTo(ObjectDB db) { if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0) { return; } bool flag = false; foreach (Module item in All) { GameObject val = Build(db, item); if (!((Object)(object)val == (Object)null) && !db.m_items.Contains(val)) { db.m_items.Add(val); flag = true; } } if (flag) { db.UpdateRegisters(); } } } [HarmonyPatch(typeof(Minimap), "UpdateExplore")] internal static class Antenna { private static float _vanilla = -1f; private static float _nextCheck; private static bool _active; public static bool Active => _active; private static void Prefix(Minimap __instance, Player player) { if (_vanilla < 0f) { _vanilla = __instance.m_exploreRadius; } if (Time.time >= _nextCheck) { _nextCheck = Time.time + 1f; Inventory val = Autopilot.Hold(((Object)(object)player != (Object)null) ? (player.GetControlledShip() ?? ((Character)player).GetStandingOnShip()) : null); _active = val != null && val.CountItems("Sonar Antenna", -1, true) > 0; } __instance.m_exploreRadius = (_active ? Mathf.Max(_vanilla, Plugin.AntennaRadius.Value) : _vanilla); } } [HarmonyPatch(typeof(Trader), "OnBought")] internal static class KeeperSold { private static bool Prefix(Trader __instance) { Keeper component = ((Component)__instance).GetComponent<Keeper>(); if ((Object)(object)component == (Object)null) { return true; } component.Bought(); return false; } } [HarmonyPatch(typeof(Trader), "OnSold")] internal static class KeeperBought { private static bool Prefix(Trader __instance) { return (Object)(object)((Component)__instance).GetComponent<Keeper>() == (Object)null; } } internal enum VoyageState { None, Underway, Anchored, Adrift, Cursed, Towed } internal static class Fleet { public const string BeaconPrefab = "HafvisirBeacon"; public const string BeaconName = "Hafvisir Beacon"; public static readonly int StateKey = StringExtensionMethods.GetStableHashCode("hafvisir_voyage"); public static readonly int NameKey = StringExtensionMethods.GetStableHashCode("hafvisir_name"); public static readonly int RouteKey = StringExtensionMethods.GetStableHashCode("hafvisir_route"); public static readonly int DepartKey = StringExtensionMethods.GetStableHashCode("hafvisir_depart"); public static readonly int SpeedKey = StringExtensionMethods.GetStableHashCode("hafvisir_speed"); public static readonly int StopAtKey = StringExtensionMethods.GetStableHashCode("hafvisir_stopat"); public static readonly int EndKey = StringExtensionMethods.GetStableHashCode("hafvisir_end"); public static readonly int RoundKey = StringExtensionMethods.GetStableHashCode("hafvisir_round"); public static readonly int DestNameKey = StringExtensionMethods.GetStableHashCode("hafvisir_dest"); public static readonly int ChargeKey = StringExtensionMethods.GetStableHashCode("hafvisir_charge"); public static bool DevNoDrive; private static readonly Dictionary<ZDOID, KeyValuePair<long, Route>> RouteCache = new Dictionary<ZDOID, KeyValuePair<long, Route>>(); public static double Now => ZNet.instance.GetTimeSeconds(); public static float TowSpeed(string shipPrefab) { return UnmannedSpeed(Fuels.All[0], shipPrefab) * Mathf.Clamp(Plugin.TowSpeed.Value, 0.1f, 2f); } public static VoyageState State(ZDO zdo) { return (VoyageState)zdo.GetInt(StateKey, 0); } public static bool Moving(VoyageState state) { if (state != VoyageState.Underway) { return state == VoyageState.Towed; } return true; } public static bool Moving(Ship ship) { ZDO val = (((Object)(object)ship != (Object)null && (Object)(object)ship.m_nview != (Object)null && ship.m_nview.IsValid()) ? ship.m_nview.GetZDO() : null); if (val != null) { return Moving(State(val)); } return false; } public static bool Stranded(Ship ship) { ZDO val = (((Object)(object)ship != (Object)null && (Object)(object)ship.m_nview != (Object)null && ship.m_nview.IsValid()) ? ship.m_nview.GetZDO() : null); if (val == null) { return false; } VoyageState voyageState = State(val); if (voyageState != VoyageState.Adrift) { return voyageState == VoyageState.Cursed; } return true; } public static void Write(ZDO zdo, Action<ZDO> change) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) bool num = !zdo.IsOwner(); if (num) { zdo.SetOwner(ZDOMan.GetSessionID()); } change(zdo); if (num) { zdo.DataRevision += 20000; if (!ZNet.instance.IsServer()) { ZDOMan.instance.ClientChanged(zdo.m_uid); } } } public static Inventory Hold(ZDO zdo, out Action save) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown save = null; ZNetView val = ZNetScene.instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { C