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 SafeHarbor v1.0.1
SafeHarbor.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SafeHarbor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("SafeHarbor")] [assembly: AssemblyTitle("SafeHarbor")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SafeHarbor { public class BerthLamp : MonoBehaviour { public int Berth; public Vector3 BaseLocalPosition; public static readonly Color OpenColor = new Color(0.25f, 1f, 0.35f); public static readonly Color ClosedColor = new Color(1f, 0.18f, 0.12f); private Light m_light; private Renderer[] m_tintRenderers; private void Awake() { m_light = ((Component)this).GetComponentInChildren<Light>(true); Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); List<Renderer> list = new List<Renderer>(); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); Material sharedMaterial = val.sharedMaterial; if (((Object)(object)sharedMaterial != (Object)null && sharedMaterial.HasProperty("_EmissionColor")) || text.Contains("lantern") || text.Contains("glass") || text.Contains("flame") || text.Contains("light") || text.Contains("lamp") || text.Contains("bulb")) { list.Add(val); } } } if (list.Count == 0) { list.AddRange(componentsInChildren); } m_tintRenderers = list.ToArray(); } public void SetOpen(bool open) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Color val = (open ? OpenColor : ClosedColor); if ((Object)(object)m_light != (Object)null) { ((Behaviour)m_light).enabled = true; m_light.color = val; } if (m_tintRenderers == null) { return; } for (int i = 0; i < m_tintRenderers.Length; i++) { Renderer val2 = m_tintRenderers[i]; if ((Object)(object)val2 == (Object)null) { continue; } Material material = val2.material; if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_Color")) { material.color = val; } if (material.HasProperty("_EmissionColor")) { material.EnableKeyword("_EMISSION"); material.SetColor("_EmissionColor", val * 1.5f); } } } } } public class BlueprintPiece { public string Name; public Vector3 Position; public Quaternion Rotation = Quaternion.identity; public Vector3 Scale = Vector3.one; } public class DockBlueprint { public string Name = "safeDock"; public string Creator = ""; public string Description = ""; public string Category = "InfinityHammer"; public Vector3 Coordinates; public Vector3 EulerRotation; public readonly List<Vector3> SnapPoints = new List<Vector3>(); public readonly List<BlueprintPiece> Pieces = new List<BlueprintPiece>(); public static DockBlueprint Load(string path) { //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: 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_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: 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) //IL_020c: 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_021f: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(path) || !File.Exists(path)) { return null; } string[] array; try { array = File.ReadAllLines(path); } catch { return null; } DockBlueprint dockBlueprint = new DockBlueprint(); CultureInfo invariantCulture = CultureInfo.InvariantCulture; bool flag = false; bool flag2 = false; for (int i = 0; i < array.Length; i++) { string text = array[i]; if (text == null) { continue; } text = text.Trim(); if (text.Length == 0) { continue; } if (text[0] == '#') { flag = false; flag2 = false; string text2 = text.Substring(1); int num = text2.IndexOf(':'); string text3 = ((num >= 0) ? text2.Substring(0, num) : text2); string text4 = ((num >= 0) ? text2.Substring(num + 1) : ""); switch (text3) { case "Name": dockBlueprint.Name = text4; break; case "Creator": dockBlueprint.Creator = text4; break; case "Description": dockBlueprint.Description = text4; break; case "Category": dockBlueprint.Category = text4; break; case "Coordinates": dockBlueprint.Coordinates = ParseVec(text4, invariantCulture); break; case "Rotation": dockBlueprint.EulerRotation = ParseVec(text4, invariantCulture); break; case "SnapPoints": flag = true; break; case "Pieces": flag2 = true; break; } } else if (flag) { dockBlueprint.SnapPoints.Add(ParseVec(text, invariantCulture)); } else if (flag2) { string[] array2 = text.Split(';'); if (array2.Length >= 13) { BlueprintPiece item = new BlueprintPiece { Name = array2[0], Position = new Vector3(ParseF(array2[2], invariantCulture), ParseF(array2[3], invariantCulture), ParseF(array2[4], invariantCulture)), Rotation = new Quaternion(ParseF(array2[5], invariantCulture), ParseF(array2[6], invariantCulture), ParseF(array2[7], invariantCulture), ParseF(array2[8], invariantCulture)), Scale = new Vector3(ParseF(array2[10], invariantCulture), ParseF(array2[11], invariantCulture), ParseF(array2[12], invariantCulture)) }; dockBlueprint.Pieces.Add(item); } } } if (dockBlueprint.Pieces.Count <= 0) { return null; } return dockBlueprint; } private static Vector3 ParseVec(string text, CultureInfo ci) { //IL_0008: 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_001e: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(text)) { return Vector3.zero; } string[] array = text.Split(','); if (array.Length < 3) { return Vector3.zero; } return new Vector3(ParseF(array[0], ci), ParseF(array[1], ci), ParseF(array[2], ci)); } private static float ParseF(string text, CultureInfo ci) { if (!float.TryParse(text, NumberStyles.Float, ci, out var result)) { return 0f; } return result; } } [Serializable] public class PieceTune { public string Name = ""; public float X; public float Y; public float Z; public float Yaw; public float Scale = 1f; } [Serializable] public class DockTuning { public float GlobalX; public float GlobalY; public float GlobalZ; public float GlobalYaw; public float GlobalScale = 1f; public float BerthX; public float BerthY; public float BerthZ; public float BerthYaw; public float LampX; public float LampY = 0.5f; public float LampZ = -6f; public float LampScale = 1f; public string DeckMaterial = ""; public List<PieceTune> Pieces = new List<PieceTune>(); } internal static class SafeHarborAppearance { public static void Apply(GameObject prefab, float deckWidth, float deckLength, bool addPilings, float pilingLength, int berths, float berthSpacing, GameObject lampPrefab, float lampScale, Vector3 lampOffset, bool statusLights) { //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) Mesh val = null; Material val2 = null; MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val3 in componentsInChildren) { if (!((Object)(object)val3.sharedMesh == (Object)null)) { MeshRenderer component = ((Component)val3).GetComponent<MeshRenderer>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)((Renderer)component).sharedMaterial == (Object)null)) { val = val3.sharedMesh; val2 = ((Renderer)component).sharedMaterial; break; } } } MeshRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Renderer)componentsInChildren2[i]).enabled = false; } Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].enabled = false; } float num = 0.3f; if ((Object)(object)val != (Object)null) { Bounds bounds = val.bounds; num = Mathf.Max(0.1f, ((Bounds)(ref bounds)).size.y); float num2 = Mathf.Max(0.01f, ((Bounds)(ref bounds)).size.x); float num3 = Mathf.Max(0.01f, ((Bounds)(ref bounds)).size.z); GameObject val4 = new GameObject("SafeHarborDeck"); val4.transform.SetParent(prefab.transform, false); val4.transform.localScale = new Vector3(deckWidth / num2, 1f, deckLength / num3); val4.transform.localPosition = new Vector3(0f, 0f - ((Bounds)(ref bounds)).max.y, 0f); val4.AddComponent<MeshFilter>().sharedMesh = val; ((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterial = val2; } else { Logger.LogWarning((object)"Safe Harbor: base dock piece had no usable mesh; falling back to a plain platform."); GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val5).name = "SafeHarborDeck"; Object.Destroy((Object)(object)val5.GetComponent<Collider>()); val5.transform.SetParent(prefab.transform, false); val5.transform.localScale = new Vector3(deckWidth, 0.4f, deckLength); val5.transform.localPosition = new Vector3(0f, -0.2f, 0f); if ((Object)(object)val2 != (Object)null) { ((Renderer)val5.GetComponent<MeshRenderer>()).sharedMaterial = val2; } } BoxCollider obj = prefab.AddComponent<BoxCollider>(); obj.size = new Vector3(deckWidth, num, deckLength); obj.center = new Vector3(0f, (0f - num) * 0.5f, 0f); if (addPilings && (Object)(object)val2 != (Object)null) { float num4 = deckWidth * 0.5f - 0.6f; float num5 = deckLength * 0.5f - 0.6f; float num6 = Mathf.Max(1f, pilingLength); Vector3[] array = (Vector3[])(object)new Vector3[4] { new Vector3(0f - num4, 0f, 0f - num5), new Vector3(num4, 0f, 0f - num5), new Vector3(0f - num4, 0f, num5), new Vector3(num4, 0f, num5) }; for (int j = 0; j < array.Length; j++) { GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)obj2).name = "SafeHarborPiling" + j; Object.Destroy((Object)(object)obj2.GetComponent<Collider>()); obj2.transform.SetParent(prefab.transform, false); obj2.transform.localPosition = new Vector3(array[j].x, (0f - num6) * 0.5f, array[j].z); obj2.transform.localScale = new Vector3(0.5f, num6 * 0.5f, 0.5f); ((Renderer)obj2.GetComponent<MeshRenderer>()).sharedMaterial = val2; } } if (statusLights && berths > 0) { float num7 = (0f - deckLength) * 0.5f + 1f; for (int k = 0; k < berths; k++) { float num8 = ((float)k - (float)(berths - 1) * 0.5f) * berthSpacing; CreateLamp(prefab.transform, lampPrefab, val2, k, new Vector3(num8, 0f, num7), lampScale, lampOffset); } } } public static void ApplyBlueprint(GameObject prefab, DockBlueprint blueprint, Vector3 center, DockTuning tuning, GameObject lampPrefab, bool statusLights, out Vector3 berthLocal, out float deckLength) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Renderer)componentsInChildren[i]).enabled = false; } Collider[] componentsInChildren2 = prefab.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Quaternion val = Quaternion.Euler(0f, tuning.GlobalYaw, 0f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(tuning.GlobalX, tuning.GlobalY, tuning.GlobalZ); float num = ((tuning.GlobalScale <= 0f) ? 1f : tuning.GlobalScale); Material val3 = null; for (int j = 0; j < blueprint.Pieces.Count; j++) { BlueprintPiece blueprintPiece = blueprint.Pieces[j]; GameObject val4 = SafeHarborPlugin.FindVanillaPrefab(blueprintPiece.Name); if ((Object)(object)val4 == (Object)null) { continue; } GameObject val5 = Object.Instantiate<GameObject>(val4, prefab.transform, false); ((Object)val5).name = "SH_BP_" + j; StripForDecoration(val5, keepColliders: true); if ((Object)(object)val3 == (Object)null) { MeshRenderer componentInChildren = val5.GetComponentInChildren<MeshRenderer>(true); if ((Object)(object)componentInChildren != (Object)null) { val3 = ((Renderer)componentInChildren).sharedMaterial; } } ApplyPieceTransform(val5.transform, blueprintPiece, j, tuning, center, val, val2, num); } deckLength = (TryGetBlueprintBounds(prefab.transform, out var bounds) ? Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z) : 18f); berthLocal = val2 + val * (num * new Vector3(tuning.BerthX, tuning.BerthY, tuning.BerthZ)); if (statusLights) { Vector3 lampOffset = val * (num * new Vector3(tuning.LampX, tuning.LampY, tuning.LampZ)); CreateLamp(prefab.transform, lampPrefab, val3, 0, berthLocal, tuning.LampScale, lampOffset); } } public static void ApplyPieceTransform(Transform child, BlueprintPiece piece, int index, DockTuning tuning, Vector3 center, Quaternion globalRot, Vector3 globalOffset, float globalScale) { //IL_000b: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00aa: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00db: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) float num = piece.Position.x - center.x; float num2 = piece.Position.y - center.y; float num3 = piece.Position.z - center.z; float num4 = 0f; float num5 = 1f; if (tuning != null && tuning.Pieces != null && index < tuning.Pieces.Count) { PieceTune pieceTune = tuning.Pieces[index]; num = pieceTune.X; num2 = pieceTune.Y; num3 = pieceTune.Z; num4 = pieceTune.Yaw; num5 = pieceTune.Scale; } child.localPosition = globalOffset + globalRot * (globalScale * new Vector3(num, num2, num3)); Vector3 eulerAngles = ((Quaternion)(ref piece.Rotation)).eulerAngles; child.localRotation = globalRot * Quaternion.Euler(eulerAngles.x, eulerAngles.y + num4, eulerAngles.z); child.localScale = Vector3.Scale(piece.Scale, Vector3.one * (globalScale * num5)); } private static void CreateLamp(Transform parent, GameObject lampPrefab, Material fallbackMaterial, int berth, Vector3 baseLocalPosition, float lampScale, Vector3 lampOffset) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0123: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(lampScale, 0.1f, 3f); GameObject val = new GameObject("SafeHarborLamp" + berth); val.SetActive(false); GameObject val2; if ((Object)(object)lampPrefab != (Object)null) { val2 = Object.Instantiate<GameObject>(lampPrefab, val.transform, false); ((Object)val2).name = "Lantern"; StripForDecoration(val2, keepColliders: false); } else { val2 = CreateFallbackLamp(fallbackMaterial); val2.transform.SetParent(val.transform, false); } Light val3 = val.GetComponentInChildren<Light>(true); if ((Object)(object)val3 == (Object)null) { val3 = val.AddComponent<Light>(); val3.type = (LightType)2; } ((Behaviour)val3).enabled = true; val3.range = Mathf.Clamp(val3.range, 6f, 10f); val3.intensity = Mathf.Clamp(val3.intensity, 0.8f, 1.4f); if (TryGetLocalBounds(val.transform, out var bounds)) { Transform transform = val2.transform; transform.localPosition -= new Vector3(0f, ((Bounds)(ref bounds)).min.y, 0f); } val.transform.SetParent(parent, false); val.transform.localPosition = baseLocalPosition + lampOffset; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * num; BerthLamp berthLamp = val.AddComponent<BerthLamp>(); berthLamp.Berth = berth; berthLamp.BaseLocalPosition = baseLocalPosition; val.SetActive(true); } private static GameObject CreateFallbackLamp(Material material) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_004f: 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_00d0: 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_00e9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("FallbackLantern"); GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)val2).name = "LampPost"; Object.Destroy((Object)(object)val2.GetComponent<Collider>()); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = new Vector3(0f, 0.9f, 0f); val2.transform.localScale = new Vector3(0.16f, 0.9f, 0.16f); if ((Object)(object)material != (Object)null) { ((Renderer)val2.GetComponent<MeshRenderer>()).sharedMaterial = material; } GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "LampBulb"; Object.Destroy((Object)(object)obj.GetComponent<Collider>()); obj.transform.SetParent(val.transform, false); obj.transform.localPosition = new Vector3(0f, 2f, 0f); obj.transform.localScale = Vector3.one * 0.5f; return val; } private static void StripForDecoration(GameObject root, bool keepColliders) { Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is Transform) && !(val is MeshFilter) && !(val is MeshRenderer) && !(val is SkinnedMeshRenderer) && !(val is Light) && !(val is LODGroup) && (!keepColliders || !(val is Collider)) && !(val is ParticleSystem) && !(val is ParticleSystemRenderer) && !(val is ReflectionProbe)) { Object.DestroyImmediate((Object)(object)val); } } } private static bool TryGetLocalBounds(Transform root, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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) //IL_00e0: 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_00d6: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(Vector3.zero, Vector3.zero); Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix; bool flag = false; MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMesh == (Object)null)) { Bounds val2 = TransformBounds(worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix, val.sharedMesh.bounds); if (!flag) { bounds = val2; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2); } } } SkinnedMeshRenderer[] componentsInChildren2 = ((Component)root).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null)) { Bounds val4 = TransformBounds(worldToLocalMatrix * ((Component)val3).transform.localToWorldMatrix, ((Renderer)val3).localBounds); if (!flag) { bounds = val4; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val4); } } } return flag; } private static bool TryGetBlueprintBounds(Transform root, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(Vector3.zero, Vector3.zero); Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix; bool flag = false; MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMesh == (Object)null) && UnderBlueprint(((Component)val).transform, root)) { Bounds val2 = TransformBounds(worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix, val.sharedMesh.bounds); if (!flag) { bounds = val2; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2); } } } return flag; } private static bool UnderBlueprint(Transform t, Transform root) { while ((Object)(object)t != (Object)null && (Object)(object)t.parent != (Object)(object)root) { t = t.parent; } if ((Object)(object)t != (Object)null) { return ((Object)t).name.StartsWith("SH_BP_"); } return false; } private static Bounds TransformBounds(Matrix4x4 matrix, Bounds local) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0028: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_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_004f: 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_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_006f: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00e4: 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) Vector3 val = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(((Bounds)(ref local)).center); Vector3 extents = ((Bounds)(ref local)).extents; Vector3 val2 = ((Matrix4x4)(ref matrix)).MultiplyVector(new Vector3(extents.x, 0f, 0f)); Vector3 val3 = ((Matrix4x4)(ref matrix)).MultiplyVector(new Vector3(0f, extents.y, 0f)); Vector3 val4 = ((Matrix4x4)(ref matrix)).MultiplyVector(new Vector3(0f, 0f, extents.z)); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(Mathf.Abs(val2.x) + Mathf.Abs(val3.x) + Mathf.Abs(val4.x), Mathf.Abs(val2.y) + Mathf.Abs(val3.y) + Mathf.Abs(val4.y), Mathf.Abs(val2.z) + Mathf.Abs(val3.z) + Mathf.Abs(val4.z)); return new Bounds(val, val5 * 2f); } } [BepInPlugin("com.safeharbor.safeharbor", "Safe Harbor", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SafeHarborPlugin : BaseUnityPlugin { private class DockVariant { public string PrefabName; public string DisplayName; public string Description; public float DeckWidth; public float DeckLength; public int Berths; public float BerthSpacing; public bool Pilings; public float PilingLength; public float LampScale; public bool UseBlueprint; public bool Small; public int Wood; public int FineWood; public int Iron; public GameObject Prefab; public bool PieceAdded; } private class BerthChoice { public ShipDock Dock; public int Berth; public int DockIndex; public float Distance; public bool Open; } public const string PluginGUID = "com.safeharbor.safeharbor"; public const string PluginName = "Safe Harbor"; public const string PluginVersion = "1.0.1"; public const string DockPrefabName = "SafeHarborDock"; public const string SmallDockPrefabName = "SafeHarborSmallDock"; private const string LanternPrefabName = "piece_dvergr_lantern_pole"; private static readonly string[] BasePieceCandidates = new string[6] { "piece_woodfloor2x2", "piece_woodfloor1x1", "piece_stonefloor2x2", "piece_stonefloor4x4", "piece_woodpole", "piece_woodwall" }; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> AddBuildPiece; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<bool> ShowHudPrompt; internal static ConfigEntry<bool> ShowMessages; internal static ConfigEntry<bool> StatusLights; internal static ConfigEntry<float> LampScale; internal static ConfigEntry<float> LampOffsetX; internal static ConfigEntry<float> LampOffsetY; internal static ConfigEntry<float> LampOffsetZ; internal static ConfigEntry<string> DeckMaterial; internal static ConfigEntry<KeyboardShortcut> GuiKey; internal static ConfigEntry<bool> UseBlueprint; internal static ConfigEntry<string> BlueprintPath; internal static ConfigEntry<string> SmallBlueprintPath; internal static ConfigEntry<bool> WebTuner; internal static ConfigEntry<int> WebPort; internal static ConfigEntry<float> DockRange; internal static ConfigEntry<float> DockDuration; internal static ConfigEntry<float> UndockDuration; internal static ConfigEntry<float> LiftHeight; internal static ConfigEntry<float> UndockDistance; internal static ConfigEntry<float> UndockSpeed; internal static ConfigEntry<float> MaxDockSpeed; internal static ConfigEntry<KeyboardShortcut> DockKey; internal static ConfigEntry<int> BerthCount; internal static ConfigEntry<float> BerthSpacing; internal static ConfigEntry<float> DeckLength; internal static ConfigEntry<bool> AddPilings; internal static ConfigEntry<float> PilingLength; internal static ConfigEntry<float> Health; internal static ConfigEntry<bool> Indestructible; internal static ConfigEntry<bool> AddSmallDock; internal static ConfigEntry<float> SmallDeckWidth; internal static ConfigEntry<float> SmallDeckLength; internal static bool PrefabRegistered; internal static readonly List<ShipDock> Docks = new List<ShipDock>(); internal static string CurrentPrompt; internal static DockBlueprint Blueprint; internal static Vector3 BlueprintCenter; internal static DockTuning Tuning = new DockTuning(); internal static string TuningPath; internal static DockBlueprint SmallBlueprint; internal static Vector3 SmallCenter; internal static DockTuning SmallTuning = new DockTuning(); internal static string SmallTuningPath; private static volatile string s_pendingApply; private static volatile int s_pendingApplyTarget; private static volatile bool s_pendingSave; private static volatile int s_pendingSaveTarget; private static SafeHarborWebGui s_web; private GUIStyle m_promptStyle; private GUIStyle m_menuTitleStyle; private GUIStyle m_menuDimStyle; private bool m_loggedDiagnostics; private bool m_loggedBasePiece; private float m_retryTimer; private bool m_menuOpen; private Ship m_menuShip; private readonly List<BerthChoice> m_choices = new List<BerthChoice>(); private readonly List<DockVariant> m_variants = new List<DockVariant>(); private bool m_guiOpen; private bool m_tuneInit; private float m_tuneX; private float m_tuneY; private float m_tuneZ; private float m_tuneScale = 1f; private Vector2 m_matScroll; private List<string> m_materialNames; private Material m_currentDeckMaterial; private Rect m_guiRect = new Rect(40f, 140f, 360f, 500f); private const int GuiWindowId = 918273645; private const string BlueprintFileName = "safeDock.blueprint"; private static Vector3 LampOffset => new Vector3(LampOffsetX.Value, LampOffsetY.Value, LampOffsetZ.Value); private void Awake() { //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle. When false Safe Harbor does nothing."); AddBuildPiece = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AddBuildPiece", true, "Add the dock pieces to the Hammer build menu. Requires a game restart."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", true, "Log docking activity to the BepInEx log. Turn off once everything behaves."); ShowHudPrompt = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowHudPrompt", true, "Show the persistent 'dock' hint on screen while steering near a dock."); ShowMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMessages", true, "Show a message when a ship docks or undocks."); StatusLights = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "StatusLights", true, "Show a status lamp per dock (green = open, red = docked). Requires a game restart."); LampScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LampScale", 1f, "Scale of the status lamps. Requires a game restart."); LampScale.Value = Mathf.Clamp(LampScale.Value, 0.1f, 3f); LampOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LampOffsetX", 0f, "Status lamp X offset (meters) from its default spot. Requires a game restart."); LampOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LampOffsetY", 0.5f, "Status lamp height (meters) above the deck. Requires a game restart."); LampOffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LampOffsetZ", 0f, "Status lamp Z offset (meters) from its default spot. Requires a game restart."); DeckMaterial = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DeckMaterial", "", "Material name to apply to the dock deck (blank = the base piece's material). Requires a game restart."); GuiKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "GuiKey", new KeyboardShortcut((KeyCode)108, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Open the Safe Harbor tuner GUI (lamp position/scale + deck material)."); UseBlueprint = ((BaseUnityPlugin)this).Config.Bind<bool>("Blueprint", "UseBlueprint", true, "Build the large dock from an Infinity Hammer / PlanBuild blueprint when one is found."); BlueprintPath = ((BaseUnityPlugin)this).Config.Bind<string>("Blueprint", "BlueprintPath", "", "Full path to the large dock blueprint. Leave blank to auto-find 'safeDock.blueprint' in the PlanBuild blueprint folders."); SmallBlueprintPath = ((BaseUnityPlugin)this).Config.Bind<string>("Blueprint", "SmallBlueprintPath", "", "Full path to the skiff dock blueprint. Leave blank to auto-find 'safeSkiff.blueprint'/'smallDock.blueprint', or to reuse the large dock blueprint."); WebTuner = ((BaseUnityPlugin)this).Config.Bind<bool>("Blueprint", "WebTuner", true, "Serve the localhost web tuner for moving the blueprint pieces live."); WebPort = ((BaseUnityPlugin)this).Config.Bind<int>("Blueprint", "WebPort", 8781, "Port for the web tuner (http://127.0.0.1:<port>/). 8777-8780 are used by other mods."); DockRange = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "DockRange", 50f, "Max distance (meters) from a dock at which the dock prompt appears."); DockDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "DockDuration", 2.5f, "Seconds the ship takes to ease into the berth and lift onto the cradle."); UndockDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "UndockDuration", 1.5f, "Seconds the ship takes to slide back out of the berth."); LiftHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "LiftHeight", 1.8f, "How far (meters) the ship is raised above the water when docked. 0 = stay at the waterline."); UndockDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "UndockDistance", 20f, "Distance (meters) forward of the berth the ship is released to when undocking. The ship is always pushed clear of the dock platform even if this is smaller."); UndockSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "UndockSpeed", 4f, "Forward push (m/s) given to the ship the moment it is released from the dock. 0 = no push."); MaxDockSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Docking", "MaxDockSpeed", 3f, "Ship must be slower than this (m/s) to dock, so you do not slam into the dock. 0 disables the check."); DockKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "DockKey", new KeyboardShortcut((KeyCode)100, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key held while at the rudder to dock/undock. Default: Shift+D."); BerthCount = ((BaseUnityPlugin)this).Config.Bind<int>("Dock", "Berths", 1, "How many ships one large dock can hold. 1 is recommended (one boat per dock). Requires a game restart."); BerthCount.Value = Mathf.Clamp(BerthCount.Value, 1, 6); BerthSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Dock", "BerthSpacing", 9f, "Distance (meters) between berths across the dock, when Berths > 1. Requires a game restart."); DeckLength = ((BaseUnityPlugin)this).Config.Bind<float>("Dock", "DeckLength", 18f, "Length (meters) of the large dock platform. Requires a game restart."); AddPilings = ((BaseUnityPlugin)this).Config.Bind<bool>("Dock", "AddPilings", true, "Add support pilings under the dock. Requires a game restart."); PilingLength = ((BaseUnityPlugin)this).Config.Bind<float>("Dock", "PilingLength", 20f, "Length (meters) of the support pilings. Longer legs let the dock stand in deeper water. Requires a game restart."); Health = ((BaseUnityPlugin)this).Config.Bind<float>("Dock", "Health", 5000f, "Hit points of the dock piece (ignored when Indestructible)."); Indestructible = ((BaseUnityPlugin)this).Config.Bind<bool>("Dock", "Indestructible", true, "Make the dock immune to all damage so it can never be destroyed."); AddSmallDock = ((BaseUnityPlugin)this).Config.Bind<bool>("SmallDock", "Enabled", true, "Also add a smaller dock for karves and rafts. Requires a game restart."); SmallDeckWidth = ((BaseUnityPlugin)this).Config.Bind<float>("SmallDock", "DeckWidth", 6f, "Width (meters) of the small dock platform. Requires a game restart."); SmallDeckLength = ((BaseUnityPlugin)this).Config.Bind<float>("SmallDock", "DeckLength", 10f, "Length (meters) of the small dock platform. Requires a game restart."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Safe Harbor 1.0.1 loading..."); LoadBlueprintAndTuning(); BuildVariants(); if (WebTuner.Value) { s_web = new SafeHarborWebGui(WebPort.Value, GetWebStateJson, QueueWebApply, QueueWebSave); s_web.Start(); } PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; PrefabManager.OnPrefabsRegistered += OnPrefabsRegistered; PieceManager.OnPiecesRegistered += OnPiecesRegistered; TryRegisterDocks(); } private void BuildVariants() { m_variants.Clear(); m_variants.Add(new DockVariant { PrefabName = "SafeHarborDock", DisplayName = "Safe Harbor Dock", Description = "A sturdy cradle for longships. Steer a ship within range, then press Shift+D at the rudder to dock and lift it out of the water.", DeckWidth = Mathf.Max(4f, (float)BerthCount.Value * BerthSpacing.Value), DeckLength = DeckLength.Value, Berths = BerthCount.Value, BerthSpacing = BerthSpacing.Value, Pilings = AddPilings.Value, PilingLength = PilingLength.Value, LampScale = LampScale.Value, UseBlueprint = (UseBlueprint.Value && Blueprint != null), Wood = 40, FineWood = 20, Iron = 10 }); if (AddSmallDock.Value) { m_variants.Add(new DockVariant { PrefabName = "SafeHarborSmallDock", DisplayName = "Safe Harbor Skiff Dock", Description = "A smaller cradle for karves and rafts. Steer a ship within range, then press Shift+D at the rudder to dock and lift it out of the water.", DeckWidth = SmallDeckWidth.Value, DeckLength = SmallDeckLength.Value, Berths = 1, BerthSpacing = 4f, Pilings = AddPilings.Value, PilingLength = PilingLength.Value, LampScale = LampScale.Value, UseBlueprint = (SmallBlueprint != null || Blueprint != null), Small = true, Wood = 20, FineWood = 8, Iron = 3 }); } } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; PrefabManager.OnPrefabsRegistered -= OnPrefabsRegistered; PieceManager.OnPiecesRegistered -= OnPiecesRegistered; if (s_web != null) { s_web.Stop(); s_web = null; } } private void OnVanillaPrefabsAvailable() { TryRegisterDocks(); } private void OnPrefabsRegistered() { TryRegisterDocks(); } private void Update() { //IL_0017: 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) UpdateRegistration(); UpdatePrompt(); ProcessWebQueue(); KeyboardShortcut value = GuiKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { m_guiOpen = !m_guiOpen; if (m_guiOpen) { InitTune(); } } if (m_guiOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void UpdateRegistration() { if (!PrefabRegistered && Enabled.Value && AddBuildPiece.Value && !((Object)(object)ZNetScene.instance == (Object)null)) { m_retryTimer += Time.deltaTime; if (!(m_retryTimer < 2f)) { m_retryTimer = 0f; TryRegisterDocks(); } } } private void TryRegisterDocks() { //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) if (PrefabRegistered || !Enabled.Value || !AddBuildPiece.Value || (Object)(object)ZNetScene.instance == (Object)null || m_variants.Count == 0) { return; } try { GameObject val = FindBasePiecePrefab(); if ((Object)(object)val == (Object)null) { if (!m_loggedDiagnostics) { m_loggedDiagnostics = true; LogDiagnostics(); } return; } if (!m_loggedBasePiece) { m_loggedBasePiece = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Safe Harbor: using base piece '" + ((Object)val).name + "'. Top: " + DescribeTopPieces(5))); } GameObject val2 = (StatusLights.Value ? FindVanillaPrefab("piece_dvergr_lantern_pole") : null); if (StatusLights.Value && (Object)(object)val2 == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Safe Harbor: could not find 'piece_dvergr_lantern_pole'; using simple status lights."); } bool prefabRegistered = true; for (int i = 0; i < m_variants.Count; i++) { DockVariant dockVariant = m_variants[i]; if ((Object)(object)dockVariant.Prefab != (Object)null) { continue; } GameObject val3 = PrefabManager.Instance.CreateClonedPrefab(dockVariant.PrefabName, val); if ((Object)(object)val3 == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Safe Harbor: failed to clone the base piece for '" + dockVariant.PrefabName + "'.")); prefabRegistered = false; continue; } StripNestedNetworkObjects(val3); ConfigurePiece(val3); ShipDock shipDock = val3.AddComponent<ShipDock>(); if (dockVariant.UseBlueprint) { DockBlueprint dockBlueprint = (dockVariant.Small ? SmallBlueprint : Blueprint); DockTuning tuning = (dockVariant.Small ? SmallTuning : Tuning); Vector3 center = (dockVariant.Small ? SmallCenter : BlueprintCenter); SafeHarborAppearance.ApplyBlueprint(val3, dockBlueprint, center, tuning, val2, StatusLights.Value, out var _, out var deckLength); shipDock.IsBlueprint = true; shipDock.IsSmall = dockVariant.Small; shipDock.BerthCount = 1; shipDock.BerthSpacing = 1f; shipDock.DeckLength = deckLength; int num = 0; Transform[] componentsInChildren = val3.GetComponentsInChildren<Transform>(true); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null && ((Object)componentsInChildren[j]).name.StartsWith("SH_BP_")) { num++; } } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Safe Harbor: blueprint dock '" + dockVariant.PrefabName + "' built with " + num + "/" + (dockBlueprint?.Pieces.Count ?? 0) + " pieces.")); } else { SafeHarborAppearance.Apply(val3, dockVariant.DeckWidth, dockVariant.DeckLength, dockVariant.Pilings, dockVariant.PilingLength, dockVariant.Berths, dockVariant.BerthSpacing, val2, dockVariant.LampScale, LampOffset, StatusLights.Value); ApplyDeckMaterial(val3); shipDock.BerthCount = dockVariant.Berths; shipDock.BerthSpacing = Mathf.Max(1f, dockVariant.BerthSpacing); shipDock.DeckLength = dockVariant.DeckLength; } PrefabManager.Instance.AddPrefab(val3); dockVariant.Prefab = val3; int num2 = val3.GetComponentsInChildren<BerthLamp>(true).Length; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Safe Harbor: registered '" + dockVariant.PrefabName + "' cloned from '" + ((Object)val).name + "' (" + num2 + " lamps).")); } PrefabRegistered = prefabRegistered; TryAddPieces(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Safe Harbor: failed to register a dock prefab: " + ex)); } } private void OnPiecesRegistered() { TryAddPieces(); } private void TryAddPieces() { //IL_004a: 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_005b: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown if (!Enabled.Value || !AddBuildPiece.Value) { return; } for (int i = 0; i < m_variants.Count; i++) { DockVariant dockVariant = m_variants[i]; if (!dockVariant.PieceAdded && !((Object)(object)dockVariant.Prefab == (Object)null)) { try { PieceConfig val = new PieceConfig { Name = dockVariant.DisplayName, Description = dockVariant.Description, PieceTable = "Hammer", Category = "Misc", Enabled = true }; val.AddRequirement("Wood", dockVariant.Wood, true); val.AddRequirement("FineWood", dockVariant.FineWood, true); val.AddRequirement("Iron", dockVariant.Iron, true); PieceManager.Instance.AddPiece(new CustomPiece(dockVariant.Prefab, false, val)); dockVariant.PieceAdded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Safe Harbor: added '" + dockVariant.DisplayName + "' build piece to the Hammer menu.")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Safe Harbor: failed to add the '" + dockVariant.DisplayName + "' piece: " + ex)); } } } } private static void ConfigurePiece(GameObject prefab) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_00ff: Unknown result type (might be due to invalid IL or missing references) Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_waterPiece = true; component.m_groundPiece = true; component.m_groundOnly = false; component.m_clipGround = false; component.m_noInWater = false; component.m_canRotate = true; component.m_canBeRemoved = true; } WearNTear component2 = prefab.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { component2.m_noSupportWear = true; component2.m_noRoofWear = true; component2.m_supports = false; component2.m_burnable = false; component2.m_materialType = (MaterialType)0; component2.m_health = Health.Value; if (Indestructible.Value) { component2.m_health = 1000000f; DamageModifiers damages = component2.m_damages; damages.m_blunt = (DamageModifier)3; damages.m_slash = (DamageModifier)3; damages.m_pierce = (DamageModifier)3; damages.m_chop = (DamageModifier)3; damages.m_pickaxe = (DamageModifier)3; damages.m_fire = (DamageModifier)3; damages.m_frost = (DamageModifier)3; damages.m_lightning = (DamageModifier)3; damages.m_poison = (DamageModifier)3; damages.m_spirit = (DamageModifier)3; damages.m_nonPlayer = (DamageModifier)3; component2.m_damages = damages; } } } private void UpdatePrompt() { //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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) CurrentPrompt = null; if (!Enabled.Value || (Object)(object)Player.m_localPlayer == (Object)null) { m_menuOpen = false; return; } Ship val = FindSteeredShip(); if ((Object)(object)val == (Object)null) { m_menuOpen = false; return; } ShipDockHandler component = ((Component)val).GetComponent<ShipDockHandler>(); KeyboardShortcut value; if ((Object)(object)component != (Object)null && component.IsBusy) { CurrentPrompt = (component.IsDocking ? "Docking..." : "Undocking..."); m_menuOpen = false; } else if ((Object)(object)component != (Object)null && component.IsDocked) { CurrentPrompt = KeyLabel() + " to undock"; m_menuOpen = false; value = DockKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { component.BeginUndock(); } } else { if (m_menuOpen && (Object)(object)m_menuShip == (Object)(object)val) { return; } m_menuOpen = false; List<BerthChoice> list = GatherChoices(val); if (list.Count == 0) { value = DockKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { Message("No docks in range."); } return; } int num = 0; for (int i = 0; i < list.Count; i++) { if (list[i].Open) { num++; } } CurrentPrompt = ((num > 0) ? (KeyLabel() + " to choose dock (" + num + " open)") : "Safe Harbor: all berths occupied"); value = DockKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { m_menuOpen = true; m_menuShip = val; m_choices.Clear(); m_choices.AddRange(list); } } } private void BeginDockWith(Ship ship, ShipDock dock, int berth) { m_menuOpen = false; if (!((Object)(object)ship == (Object)null) && !((Object)(object)dock == (Object)null) && berth >= 0) { ((Component)ship).gameObject.AddComponent<ShipDockHandler>().BeginDock(ship, dock, berth); } } private static List<BerthChoice> GatherChoices(Ship ship) { //IL_000c: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) List<BerthChoice> list = new List<BerthChoice>(); Vector3 position = ((Component)ship).transform.position; float value = DockRange.Value; Dictionary<ShipDock, int> dictionary = new Dictionary<ShipDock, int>(); for (int i = 0; i < Docks.Count; i++) { ShipDock shipDock = Docks[i]; if ((Object)(object)shipDock == (Object)null) { continue; } int capacity = shipDock.Capacity; for (int j = 0; j < capacity; j++) { float num = Vector3.Distance(position, shipDock.BerthWorldPosition(j)); if (!(num > value)) { if (!dictionary.ContainsKey(shipDock)) { dictionary[shipDock] = dictionary.Count + 1; } list.Add(new BerthChoice { Dock = shipDock, Berth = j, DockIndex = dictionary[shipDock], Distance = num, Open = !shipDock.IsBerthOccupied(j) }); } } } list.Sort((BerthChoice a, BerthChoice b) => (a.Open != b.Open) ? ((!a.Open) ? 1 : (-1)) : a.Distance.CompareTo(b.Distance)); return list; } internal static Ship FindSteeredShip() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || Ship.Instances == null) { return null; } long playerID = localPlayer.GetPlayerID(); List<IMonoUpdater> instances = Ship.Instances; for (int i = 0; i < instances.Count; i++) { IMonoUpdater obj = instances[i]; Ship val = (Ship)(object)((obj is Ship) ? obj : null); if (!((Object)(object)val == (Object)null)) { ShipControlls shipControlls = val.m_shipControlls; if (!((Object)(object)shipControlls == (Object)null) && shipControlls.HaveValidUser() && shipControlls.GetUser() == playerID) { return val; } } } return null; } private static string KeyLabel() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = DockKey.Value; string text = ""; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { text = text + ModifierName(modifier) + "+"; } return text + ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString(); } private unsafe static string ModifierName(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown switch (key - 303) { case 0: case 1: return "Shift"; case 2: case 3: return "Ctrl"; case 4: case 5: return "Alt"; default: return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } internal static void Message(string text) { if (ShowMessages.Value && !((Object)(object)MessageHud.instance == (Object)null)) { MessageHud.instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false, false); } } internal static void Debug(string text) { if (DebugLogging.Value) { Logger.LogInfo((object)("Safe Harbor: " + text)); } } private void OnGUI() { if (Enabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null)) { DrawMenu(); DrawPrompt(); DrawTuner(); } } private void DrawPrompt() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!m_menuOpen && ShowHudPrompt.Value && !string.IsNullOrEmpty(CurrentPrompt)) { if (m_promptStyle == null) { m_promptStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 20, fontStyle = (FontStyle)1 }; m_promptStyle.normal.textColor = Color.white; } float num = 500f; float num2 = 36f; Rect val = new Rect(((float)Screen.width - num) * 0.5f, (float)Screen.height * 0.72f, num, num2); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(val, CurrentPrompt, m_promptStyle); } } private void DrawMenu() { //IL_0076: 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: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Invalid comparison between Unknown and I4 //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Invalid comparison between Unknown and I4 //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Invalid comparison between Unknown and I4 //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Invalid comparison between Unknown and I4 //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Invalid comparison between Unknown and I4 //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected I4, but got Unknown if (!m_menuOpen || (Object)(object)m_menuShip == (Object)null) { return; } EnsureMenuStyles(); float num = 520f; float num2 = 32f; float num3 = 34f; float num4 = 12f; float num5 = num3 + (float)m_choices.Count * num2 + num4 * 2f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num) * 0.5f, ((float)Screen.height - num5) * 0.5f, num, num5); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.85f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + num4, ((Rect)(ref val)).width, num3), "Select a dock", m_menuTitleStyle); float num6 = ((Rect)(ref val)).y + num4 + num3; int num7 = 0; Rect val2 = default(Rect); for (int i = 0; i < m_choices.Count; i++) { BerthChoice berthChoice = m_choices[i]; ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + num4, num6, num - num4 * 2f, num2 - 2f); string text = "Dock " + berthChoice.DockIndex; if (berthChoice.Dock.Capacity > 1) { text = text + " - Berth " + (berthChoice.Berth + 1); } text = text + " (" + Mathf.RoundToInt(berthChoice.Distance) + " m)"; if (berthChoice.Open) { num7++; if (GUI.Button(val2, num7 + ". " + text + " - Open")) { BeginDockWith(m_menuShip, berthChoice.Dock, berthChoice.Berth); return; } } else { GUI.Label(val2, " " + text + " - Docked", m_menuDimStyle); } num6 += num2; } Event current = Event.current; if (current == null) { return; } if ((int)current.type == 4 && (int)current.keyCode == 27) { m_menuOpen = false; } else { if ((int)current.type != 4 || (int)current.keyCode < 49 || (int)current.keyCode > 57) { return; } int num8 = current.keyCode - 49; int num9 = 0; for (int j = 0; j < m_choices.Count; j++) { if (m_choices[j].Open) { if (num9 == num8) { BeginDockWith(m_menuShip, m_choices[j].Dock, m_choices[j].Berth); break; } num9++; } } } } private void EnsureMenuStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0034: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (m_menuTitleStyle == null) { m_menuTitleStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 20, fontStyle = (FontStyle)1 }; m_menuTitleStyle.normal.textColor = Color.white; m_menuDimStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 16 }; m_menuDimStyle.normal.textColor = new Color(0.75f, 0.45f, 0.45f); } } private static void ApplyDeckMaterial(GameObject prefab) { if (string.IsNullOrEmpty(DeckMaterial.Value)) { return; } Material val = FindMaterial(DeckMaterial.Value); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("Safe Harbor: deck material '" + DeckMaterial.Value + "' not found.")); return; } Transform val2 = prefab.transform.Find("SafeHarborDeck"); if ((Object)(object)val2 != (Object)null) { MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sharedMaterial = val; } } } private static Material FindMaterial(string name) { Material[] array = Resources.FindObjectsOfTypeAll<Material>(); foreach (Material val in array) { if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } private void InitTune() { if (!m_tuneInit) { m_tuneInit = true; m_tuneX = LampOffsetX.Value; m_tuneY = LampOffsetY.Value; m_tuneZ = LampOffsetZ.Value; m_tuneScale = LampScale.Value; m_currentDeckMaterial = (string.IsNullOrEmpty(DeckMaterial.Value) ? null : FindMaterial(DeckMaterial.Value)); } EnsureMaterialNames(); } private void EnsureMaterialNames() { if (m_materialNames != null) { return; } m_materialNames = new List<string>(); HashSet<string> hashSet = new HashSet<string>(); Material[] array = Resources.FindObjectsOfTypeAll<Material>(); foreach (Material val in array) { if (!((Object)(object)val == (Object)null)) { string name = ((Object)val).name; if (!string.IsNullOrEmpty(name) && !name.StartsWith("Hidden", StringComparison.OrdinalIgnoreCase) && !name.StartsWith("Sprites", StringComparison.OrdinalIgnoreCase) && (val.HasProperty("_MainTex") || val.HasProperty("_Color")) && hashSet.Add(name)) { m_materialNames.Add(name); } } } m_materialNames.Sort(StringComparer.OrdinalIgnoreCase); } private void ApplyTune() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) Vector3 lampOffset = default(Vector3); ((Vector3)(ref lampOffset))..ctor(m_tuneX, m_tuneY, m_tuneZ); for (int i = 0; i < Docks.Count; i++) { ShipDock shipDock = Docks[i]; if (!((Object)(object)shipDock == (Object)null)) { if (shipDock.IsBlueprint) { shipDock.ApplyBlueprintTuning(); } else { shipDock.ApplyLayout(lampOffset, m_tuneScale, m_currentDeckMaterial, applyMaterial: true); } } } } private void SaveTune() { LampOffsetX.Value = m_tuneX; LampOffsetY.Value = m_tuneY; LampOffsetZ.Value = m_tuneZ; LampScale.Value = m_tuneScale; Message("Safe Harbor settings saved."); } private void DrawTuner() { //IL_0010: 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_0030: Expected O, but got Unknown //IL_002b: 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) if (m_guiOpen) { m_guiRect = GUILayout.Window(918273645, m_guiRect, new WindowFunction(DrawTunerWindow), "Safe Harbor Tuner", Array.Empty<GUILayoutOption>()); } } private void DrawTunerWindow(int id) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("Changes apply live to all placed docks.", Array.Empty<GUILayoutOption>()); float num = LabeledSlider("Lamp X", m_tuneX, -10f, 10f); float num2 = LabeledSlider("Lamp Y", m_tuneY, -10f, 10f); float num3 = LabeledSlider("Lamp Z", m_tuneZ, -10f, 10f); float num4 = LabeledSlider("Lamp Scale", m_tuneScale, 0.1f, 3f); if (num != m_tuneX || num2 != m_tuneY || num3 != m_tuneZ || num4 != m_tuneScale) { m_tuneX = num; m_tuneY = num2; m_tuneZ = num3; m_tuneScale = num4; ApplyTune(); } GUILayout.Space(6f); GUILayout.Label("Deck material: " + (((Object)(object)m_currentDeckMaterial != (Object)null) ? ((Object)m_currentDeckMaterial).name : "(base)"), Array.Empty<GUILayoutOption>()); m_matScroll = GUILayout.BeginScrollView(m_matScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(200f) }); if (GUILayout.Button("(use base piece material)", Array.Empty<GUILayoutOption>())) { m_currentDeckMaterial = null; DeckMaterial.Value = ""; ApplyTune(); } for (int i = 0; i < m_materialNames.Count; i++) { string text = m_materialNames[i]; if (GUILayout.Button(text, Array.Empty<GUILayoutOption>())) { m_currentDeckMaterial = FindMaterial(text); DeckMaterial.Value = text; ApplyTune(); } } GUILayout.EndScrollView(); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Save defaults", Array.Empty<GUILayoutOption>())) { SaveTune(); } if (GUILayout.Button("Close", Array.Empty<GUILayoutOption>())) { m_guiOpen = false; } GUILayout.EndHorizontal(); GUI.DragWindow(); } private static float LabeledSlider(string label, float value, float min, float max) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label + ": " + value.ToString("0.00"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); float result = GUILayout.HorizontalSlider(value, min, max, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); return result; } private void LoadBlueprintAndTuning() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) string text = ResolveBlueprintPath(small: false); Blueprint = DockBlueprint.Load(text); if (Blueprint == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Safe Harbor: no large dock blueprint found" + (string.IsNullOrEmpty(text) ? "." : (" at '" + text + "'.")) + " Using the built-in model.")); } else { BlueprintCenter = ComputeCenter(Blueprint); TuningPath = Path.Combine(Paths.ConfigPath, "safeharbor_dock.json"); Tuning = LoadTuning(TuningPath); if (Tuning == null) { Tuning = new DockTuning(); } EnsureTuningPieces(Blueprint, Tuning, BlueprintCenter); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Safe Harbor: loaded large blueprint '" + Blueprint.Name + "' (" + Blueprint.Pieces.Count + " pieces).")); } SmallBlueprint = DockBlueprint.Load(ResolveBlueprintPath(small: true)); if (SmallBlueprint == null) { SmallBlueprint = Blueprint; SmallCenter = BlueprintCenter; } else { SmallCenter = ComputeCenter(SmallBlueprint); } if (SmallBlueprint != null) { SmallTuningPath = Path.Combine(Paths.ConfigPath, "safeharbor_skiff.json"); SmallTuning = LoadTuning(SmallTuningPath); if (SmallTuning == null) { SmallTuning = new DockTuning(); } EnsureTuningPieces(SmallBlueprint, SmallTuning, SmallCenter); if (SmallBlueprint != Blueprint) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Safe Harbor: loaded skiff blueprint '" + SmallBlueprint.Name + "' (" + SmallBlueprint.Pieces.Count + " pieces).")); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Safe Harbor: no skiff blueprint; the skiff dock reuses the large blueprint (separate tuning)."); } } } private static List<string> BlueprintDirs() { List<string> list = new List<string>(); try { list.Add(Path.Combine(Paths.ConfigPath, "PlanBuild", "blueprints")); list.Add(Path.Combine(Paths.GameRootPath, "BepInEx", "config", "PlanBuild", "blueprints")); list.Add(Path.Combine(Paths.ConfigPath, "PlanBuild")); list.Add(Path.Combine(Paths.GameRootPath, "BepInEx", "config", "PlanBuild")); } catch { } return list; } private static string FindBlueprintFile(string[] names) { List<string> list = BlueprintDirs(); for (int i = 0; i < list.Count; i++) { for (int j = 0; j < names.Length; j++) { string text = Path.Combine(list[i], names[j]); if (File.Exists(text)) { return text; } } } return null; } private static string ResolveBlueprintPath(bool small) { if (small) { if (!string.IsNullOrEmpty(SmallBlueprintPath.Value)) { return SmallBlueprintPath.Value; } return FindBlueprintFile(new string[4] { "safeSkiff.blueprint", "smallDock.blueprint", "safeDockSmall.blueprint", "skiff.blueprint" }) ?? ResolveBlueprintPath(small: false); } if (!string.IsNullOrEmpty(BlueprintPath.Value)) { return BlueprintPath.Value; } string text = FindBlueprintFile(new string[1] { "safeDock.blueprint" }); if (text != null) { return text; } List<string> list = BlueprintDirs(); if (list.Count <= 0) { return ""; } return Path.Combine(list[0], "safeDock.blueprint"); } private static Vector3 ComputeCenter(DockBlueprint blueprint) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (blueprint == null || blueprint.Pieces.Count == 0) { return Vector3.zero; } Vector3 val = blueprint.Pieces[0].Position; Vector3 val2 = val; for (int i = 1; i < blueprint.Pieces.Count; i++) { Vector3 position = blueprint.Pieces[i].Position; val = Vector3.Min(val, position); val2 = Vector3.Max(val2, position); } return (val + val2) * 0.5f; } private static void EnsureTuningPieces(DockBlueprint blueprint, DockTuning tuning, Vector3 center) { //IL_0066: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (blueprint != null && (tuning.Pieces == null || tuning.Pieces.Count != blueprint.Pieces.Count)) { tuning.Pieces = new List<PieceTune>(); for (int i = 0; i < blueprint.Pieces.Count; i++) { BlueprintPiece blueprintPiece = blueprint.Pieces[i]; tuning.Pieces.Add(new PieceTune { Name = blueprintPiece.Name, X = blueprintPiece.Position.x - center.x, Y = blueprintPiece.Position.y - center.y, Z = blueprintPiece.Position.z - center.z, Yaw = 0f, Scale = 1f }); } } } private static DockTuning LoadTuning(string path) { try { if (!string.IsNullOrEmpty(path) && File.Exists(path)) { return JsonUtility.FromJson<DockTuning>(File.ReadAllText(path)); } } catch (Exception ex) { Logger.LogWarning((object)("Safe Harbor: could not read tuning file: " + ex.Message)); } return null; } private static void SaveTuning(int target) { string text = ((target == 1) ? SmallTuningPath : TuningPath); DockTuning dockTuning = ((target == 1) ? SmallTuning : Tuning); if (string.IsNullOrEmpty(text)) { return; } try { File.WriteAllText(text, JsonUtility.ToJson((object)dockTuning, true)); } catch (Exception ex) { Logger.LogWarning((object)("Safe Harbor: could not save tuning file: " + ex.Message)); } } private void ApplyTuningToAll() { for (int i = 0; i < Docks.Count; i++) { ShipDock shipDock = Docks[i]; if ((Object)(object)shipDock != (Object)null) { shipDock.ApplyBlueprintTuning(); } } for (int j = 0; j < m_variants.Count; j++) { DockVariant dockVariant = m_variants[j]; if ((Object)(object)dockVariant.Prefab != (Object)null) { ShipDock component = dockVariant.Prefab.GetComponent<ShipDock>(); if ((Object)(object)component != (Object)null) { component.ApplyBlueprintTuning(); } } } } private static string GetWebStateJson(int target) { try { return JsonUtility.ToJson((object)((target == 1) ? SmallTuning : Tuning)); } catch { return "{}"; } } private static void QueueWebApply(int target, string json) { s_pendingApplyTarget = target; s_pendingApply = json; } private static void QueueWebSave(int target) { s_pendingSaveTarget = target; s_pendingSave = true; } private void ProcessWebQueue() { //IL_0046: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) string text = s_pendingApply; if (text != null) { int num = s_pendingApplyTarget; s_pendingApply = null; DockBlueprint dockBlueprint = ((num == 1) ? SmallBlueprint : Blueprint); DockTuning dockTuning = ((num == 1) ? SmallTuning : Tuning); Vector3 center = ((num == 1) ? SmallCenter : BlueprintCenter); try { if (dockBlueprint != null) { JsonUtility.FromJsonOverwrite(text, (object)dockTuning); EnsureTuningPieces(dockBlueprint, dockTuning, center); ApplyTuningToAll(); } } catch (Exception ex) { Logger.LogWarning((object)("Safe Harbor: bad tuner payload: " + ex.Message)); } } if (s_pendingSave) { s_pendingSave = false; SaveTuning(s_pendingSaveTarget); } } private static GameObject FindBasePiecePrefab() { List<GameObject> list = CollectPiecePrefabs(); GameObject result = null; float num = float.MinValue; for (int i = 0; i < list.Count; i++) { GameObject val = list[i]; if (!((Object)(object)val == (Object)null)) { float num2 = ScorePiece(val); if (num2 > num) { num = num2; result = val; } } } return result; } private static List<GameObject> CollectPiecePrefabs() { List<GameObject> list = new List<GameObject>(); HashSet<int> hashSet = new HashSet<int>(); Piece[] array = Resources.FindObjectsOfTypeAll<Piece>(); if (array != null) { Piece[] array2 = array; foreach (Piece val in array2) { if (!((Object)(object)val == (Object)null)) { GameObject gameObject = ((Component)val).gameObject; if (!((Object)(object)gameObject == (Object)null) && !IsOwnPrefab(((Object)gameObject).name) && hashSet.Add(((Object)gameObject).GetInstanceID())) { list.Add(gameObject); } } } } if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null) { foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { continue; } PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces; if ((Object)(object)buildPieces == (Object)null || buildPieces.m_pieces == null) { continue; } foreach (GameObject piece in buildPieces.m_pieces) { if (!((Object)(object)piece == (Object)null) && !((Object)(object)piece.GetComponent<Piece>() == (Object)null) && !IsOwnPrefab(((Object)piece).name) && hashSet.Add(((Object)piece).GetInstanceID())) { list.Add(piece); } } } } return list; } private static bool IsOwnPrefab(string name) { if (!string.IsNullOrEmpty(name)) { return name.StartsWith("SafeHarbor", StringComparison.OrdinalIgnoreCase); } return false; } private static float ScorePiece(GameObject go) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) string text = ((Object)go).name.ToLowerInvariant(); if ((Object)(object)go.GetComponent<Ship>() != (Object)null) { return -100000f; } if (text.Contains("ship") || text.Contains("boat") || text.Contains("raft") || text.Contains("karve") || text.Contains("cart") || text.Contains("wagon") || text.Contains("portal") || text.Contains("armorstand") || text.Contains("throne") || text.Contains("bed") || text.Contains("stair") || text.Contains("roof") || text.Contains("wall") || text.Contains("door") || text.Contains("gate") || text.Contains("window") || text.Contains("lantern") || text.Contains("torch") || text.Contains("ladder")) { return -100000f; } if (text.Contains("grausten") || text.Contains("blackmarble") || text.Contains("marble") || text.Contains("stone") || text.Contains("iron") || text.Contains("flametal") || text.Contains("crystal") || text.Contains("metal")) { return -100000f; } if (!TryGetPieceFootprint(go, out var bounds)) { return -100000f; } float num = Mathf.Min(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z); if (num < 1.5f) { return -100000f; } if (((Bounds)(ref bounds)).size.y > Mathf.Max(1.2f, num * 0.6f)) { return -100000f; } float num2 = ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.z; if (text.Contains("woodfloor") || text.Contains("wood_floor") || text.Contains("wood floor")) { num2 += 12000f; } else if (text.Contains("floor")) { num2 += 6000f; } else if (text.Contains("ground")) { num2 += 2000f; } else if (text.Contains("platform")) { num2 += 1000f; } if (text.Contains("wood")) { num2 += 4000f; } if (text.StartsWith("piece_")) { num2 += 200f; } return num2; } private static string DescribeTopPieces(int count) { List<GameObject> list = CollectPiecePrefabs(); List<KeyValuePair<string, float>> list2 = new List<KeyValuePair<string, float>>(); for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] != (Object)null) { list2.Add(new KeyValuePair<string, float>(((Object)list[i]).name, ScorePiece(list[i]))); } } list2.Sort((KeyValuePair<string, float> a, KeyValuePair<string, float> b) => b.Value.CompareTo(a.Value)); string text = ""; int num = Mathf.Min(count, list2.Count); for (int num2 = 0; num2 < num; num2++) { if (num2 > 0) { text += ", "; } text = text + list2[num2].Key + "(" + Mathf.RoundToInt(list2[num2].Value) + ")"; } return text; } private static void StripNestedNetworkObjects(GameObject prefab) { Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is Transform) && !((Object)(object)val.gameObject == (Object)(object)prefab) && (val is ZNetView || val is ZSyncTransform)) { Object.Destroy((Object)(object)val); } } } private static bool TryGetPieceFootprint(GameObject go, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00c2: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(Vector3.zero, Vector3.zero); MeshFilter[] componentsInChildren = go.GetComponentsInChildren<MeshFilter>(true); bool flag = false; Vector3 val3 = default(Vector3); Bounds val4 = default(Bounds); foreach (MeshFilter val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMesh == (Object)null)) { Bounds bounds2 = val.sharedMesh.bounds; Transform transform = ((Component)val).transform; Vector3 val2 = go.transform.InverseTransformPoint(transform.TransformPoint(((Bounds)(ref bounds2)).center)); Vector3 lossyScale = transform.lossyScale; ((Vector3)(ref val3))..ctor(Mathf.Abs(lossyScale.x) * ((Bounds)(ref bounds2)).size.x, Mathf.Abs(lossyScale.y) * ((Bounds)(ref bounds2)).size.y, Mathf.Abs(lossyScale.z) * ((Bounds)(ref bounds2)).size.z); ((Bounds)(ref val4))..ctor(val2, val3); if (!flag) { bounds = val4; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val4); } } } return flag; } internal static GameObject FindVanillaPrefab(string name) { PrefabManager instance = PrefabManager.Instance; GameObject val = ((instance != null) ? instance.GetPrefab(name) : null); if ((Object)(object)val != (Object)null) { return val; } if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null) { foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab != (Object)null && string.Equals(((Object)prefab).name, name, StringComparison.OrdinalIgnoreCase)) { return prefab; } } } if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null) { foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item != (Object)null && string.Equals(((Object)item).name, name, StringComparison.OrdinalIgnoreCase)) { return item; } } } Piece[] array = Resources.FindObjectsOfTypeAll<Piece>(); if (array != null) { Piece[] array2 = array; foreach (Piece val2 in array2) { if ((Object)(object)val2 != (Object)null && string.Equals(((Object)((Component)val2).gameObject).name, name, StringComparison.OrdinalIgnoreCase)) { return ((Component)val2).gameObject; } } } return null; } private static GameObject FindPieceInHammerTable() { if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { return null; } GameObject val = null; foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { continue; } PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces; if ((Object)(object)buildPieces == (Object)null || buildPieces.m_pieces == null) { continue; } foreach (GameObject piece in buildPieces.m_pieces) { if (!((Object)(object)piece == (Object)null) && !((Object)(object)piece.GetComponent<Piece>() == (Object)null)) { if ((Object)(object)val == (Object)null) { val = piece; } if (IsCandidateName(((Object)piece).name)) { return piece; } } } } return val; } private static GameObject FindPieceViaResources() { Piece[] array = Resources.FindObjectsOfTypeAll<Piece>(); if (array == null) { return null; } GameObject val = null; foreach (Piece val2 in array) { if (!((Object)(object)val2 == (Object)null)) { GameObject gameObject = ((Component)val2).gameObject; if ((Object)(object)val == (Object)null) { val = gameObject; } if (IsCandidateName(((Object)gameObject).name)) { return gameObject; } } } return val; } private static bool IsCandidateName(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLowerInvariant(); string[] basePieceCandidates = BasePieceCandidates; foreach (string text2 in basePieceCandidates) { if (text == text2) { return true; } } return false; } private static void LogDiagnostics() { int num = (((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null) ? ZNetScene.instance.m_prefabs.Count : (-1)); int num2 = 0; if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null) { foreach (GameObject prefab in ZNetScene.instance.m